From: resander on 21 Apr 2010 12:43 I am working on software that manipulates SQL databases via a GUI. It is written in C or C++ without classes and compiled on Linux. Would also want it to run on Windows eventually. This software has essentially one entry procedure: int guidb ( int appno , int recaddress ); // in C which returns an outcome as an int, takes an int appno which specifies application and an address of a record in recaddress. The latter is used for passing the memory address of any recordtype variable and is cast to a byte address inside guidb. guidb uses appno to locate field-offsets and length of the recordtype in tables built by initialisation functions for all recordtypes that take part. Typical use in C/C++: typedef struct { int prodcode; float price; char descr [50]... } PRODUCT; typedef struct { bool bitesyou; int speciescode; char name[20] ... } ANIMAL ; void getproduct ( PRODUCT * pout , int * resultout ) { *resultout = guidb ( 0 , (int)pout ) ; } void addtozoo ( ANIMAL * a , int * resultout ) { *resultout = guidb ( 1 , (int)a ) ; } PRODUCT prod ; ANIMAL addthis ; int outcome ; // use as... getproduct ( &prod , &outcome ); // get addthis animal data then addtozoo ( &addthis , &outcome ); All wrappers like getproduct and addtozoo are automatically generated from other specs. That is easy in C by using fldoffset macro to get field offsets and sizeof(rectypename) to get record length and a cast that changes the interpretation of address to an int. Desired use in Ada (same as above): type PRODUCT is RECORD int prodcode; float price; char descr [50]...END RECORD; procedure getproduct ( p : out PRODUCT ; result : out int ) is begin result = guidb ( 0 , address_of(p) how ??? ) ; end prod : PRODUCT; outcome : int ; getproduct ( prod , outcome ); To be able to use the guidb with Ada I need to know how to: - get the memory address carried (how?) by the record formal parameter - obtain field offsets for a record type - obtain length of a record object/variable How to do this in in Ada? If it cannot be done, can the interface above be changed to make it possible? Ken
From: Dmitry A. Kazakov on 21 Apr 2010 13:39 On Wed, 21 Apr 2010 09:43:02 -0700 (PDT), resander wrote: > I am working on software that manipulates SQL databases via a GUI. It > is written in C or C++ without classes and compiled on Linux. Would > also want it to run on Windows eventually. This software has > essentially one entry procedure: > > int guidb ( int appno , int recaddress ); // in C This is awful even on C standards. > which returns an outcome as an int, takes an int appno which specifies > application and an address of a record in recaddress. The latter is > used for passing the memory address of any recordtype variable and is > cast to a byte address inside guidb. [...] > Desired use in Ada (same as above): > > type PRODUCT is RECORD int prodcode; float price; char descr > [50]...END RECORD; > > procedure getproduct ( p : out PRODUCT ; result : out int ) is > begin > result = guidb ( 0 , address_of(p) how ??? ) ; > end > > prod : PRODUCT; > outcome : int ; [...] > How to do this in in Ada? If it cannot be done, can the interface > above be changed to make it possible? Make it a generic function: SQL_Error : exception; generic type Data_Type is private; function Generic_Get (No : Integer) return Data_Type; The implementation of: with Ada.Exceptions; use Ada.Exceptions; with Interfaces.C; use Interfaces.C; function Generic_Get (No : Integer) return Data_Type is function Internal (No : int; Data : access Data_Type) return int; pragma Import (C, Internal, "guilib"); Data : aliased Data_Type; Result : int; begin Result := Internal (int (No), Data'Access); if Result /= 0 then Raise_Exception (SQL_Error'Identity, "Error code:" & int'Image (Result)); else return Data; end if; end Generic_Get; Declare a type you need, e.g. Product: type Product is record Code : int; Price : float; Descr : char_array (1..50); end record; pragma Convention (C, Product); -- Note this pragma! Instantiate the function: function Get is new Generic_Get (Product); Use it as: X : Product := Get (0); -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de
From: Robert A Duff on 26 Apr 2010 14:16 resander <kresander(a)gmail.com> writes: > On Apr 22, 10:12�pm, Keith Thompson <ks...(a)mib.org> wrote: >> There is no guarantee that an int can hold the value of an address, >> and there are common systems (including Linux systems) where it >> can't. �Worse, you're not likely to get a warning if you convert >> a pointer to int, even if there's a loss of information. Why? I'd think if int is smaller than whatever*, then a cast to int clearly deserves a warning. >> The right type for this parameter is void* (which is roughly >> analogous to Ada's System.Address). Yeah, roughly. System.Address is somewhat lower level than C's void*. > Thank you all for your concerns about using an int for passing an > address. The interface actually uses a void * (could also be char * as > that is what is needed), but I changed it for the post because I > thought an all-int interface would be easier to handle at the Ada-to-C > boundary. That seems to have backfired! You should look at section B (especially B.3) of the Ada RM. There's a type char_star you can use. There's no void_star. I'm not sure why -- probably this part of Ada predates void* in C, and nobody bothered to upgrade Ada to match the new C. > Q1. > Addresses are not negative. How do I output a System.Address? In GNAT, there is a function System.Address_Image. Look at the file s-addima.ads in your GNAT distribution. Beware: this is not portable to other Ada compilers. - Bob
From: Maciej Sobczak on 26 Apr 2010 17:20 On 26 Kwi, 21:57, Keith Thompson <ks...(a)mib.org> wrote: > But C still requires char* and void* to have the same representation. > > But in the Ada RM, I only see char_star in an example: > > subtype Char_Star is Char_Ptrs.Pointer; I use this: subtype Void_Ptr is System.Address; It works like a charm. Please note that in order to link Ada with C there is a need for a *pair* of *compatible* compilers - you cannot compile the Ada part with a random Ada compiler and a C part with a random C compiler and expect them to work together. There is a lot of hand-waving in the multilanguage development, which means lots of under-the-table assumptions can be taken for granted even though they are not explicitly covered by any of the language standards. -- Maciej Sobczak * http://www.inspirel.com YAMI4 - Messaging Solution for Distributed Systems http://www.inspirel.com/yami4
From: Randy Brukardt on 26 Apr 2010 21:31 "Robert A Duff" <bobduff(a)shell01.TheWorld.com> wrote in message news:wcceii1g308.fsf(a)shell01.TheWorld.com... > Keith Thompson <kst-u(a)mib.org> writes: .... >> The document I'm looking at is "Ada Reference Manual, ISO/IEC >> 8652:2007(E) Ed. 3", "ISO/IEC 8652:1995(E) with Technical Corrigendum 1 >> and Amendment 1". Is that the most current version? > > No. The most current standard is here: > > http://www.ada-auth.org/ Actually, the title Keith gives is that of the most recent "official" consolidated edition. And the on-line versions of the Ada 2005 stuff are found in http://www.adaic.org/standards/ada05.html (You can get the source and tools for generating the standard from www.ada-auth.org, but that is something that very few people need.) > after you rummage aroung a bit. Look for the Ada 2005 version. The > most current future to-be-standardized version (for Ada 2012) is here: > > http://www.adaic.org/standards/ada1z.html > > Note that this one has no official ISO status yet. Note that the above URL is going to change drastically when the next draft version is posted (probably next week). It is going to move to www.ada-auth.org and will be named Ada 2012 (instead of the "1z"). I'll try to maintain some sort of forwarding, but it is best to change you bookmarks then. So to sum up, Bob got it exactly backwards. ;-) .... >> There's no need for nul, wide_nul, and char32_nul to be >> implementation-defined; they're all zero by definition: >> >> nul : constant char := char'val(0); >> ... >> wide_nul : constant wchar_t := wchar_t'val(0); >> ... >> char32_nul : constant char32_t := char32_t'val(0); > > Yes, I think that makes sense. See also AI95-00037. > >> C doesn't actually have a type corresponding to char32_t; it has >> wchar_t, but its size is implementation-defined. I believe that the char16 and char32 types were to match some proposed C update; not sure if that was ever adopted. Ah, here's what AI95-00285-1 has to say on the subject: -- SC22/WG14 is planning to include support for Unicode 16- and 32-bit characters -- in C. Their proposal is presented in ISO/IEC TR 19769:2004 -- (http://www.open-std.org/jtc1/sc22//WG14/www/docs/n1040.pdf). In order to -- provide compatibility with the upcoming C standard, new types are added to -- Interfaces.C that correspond to C char16_t and char32_t. It is recognized that -- adding new declarations to predefined units can cause incompatibilities, but it -- is thought that the new identifiers are unlikely to conflict with existing -- code. We may have jumped the gun on adding these, but as Bob noted, we're not going to remove them as the incompatibility would be significant and it's harmless to have them. Randy.
|
Next
|
Last
Pages: 1 2 Prev: Ada help file indexed by keyword Next: InformationWeek Gives Ada Black Eye |