comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: How to access this package written in C?
Date: Fri, 23 Apr 2010 16:15:31 +0200
Date: 2010-04-23T16:15:31+02:00	[thread overview]
Message-ID: <5h5csoxoxqv7.1i6yifddkcfhi$.dlg@40tude.net> (raw)
In-Reply-To: e98bcf01-46cc-44dd-b57b-3cc7e273d9e2@j21g2000yqh.googlegroups.com

On Fri, 23 Apr 2010 05:58:05 -0700 (PDT), resander wrote:

> It may help if I give some background info, so just briefly the
> program (with guidb as the main entry routine) moves record data to/
> from GUI dialogs and to and from SQL databases via ODBC.

There is GNADE ODBC, Ada bindings to ODBC. So you can drop C/C++
altogether.

> for record
>    code : integer; bcode : character;
>    ccode : character; third : integer;
>    descr : String(1..10); price : float;
> by:
>  prod : PRODUCT;
>  a: System.Address;
>    function Conv is new Ada.Unchecked_Conversion (
>                      Source => System.Address,
>                      Target => Integer);
>   ...
>   a := prod'Address;
>   put( "Prodrecord address: " );
>   s := conv ( a ) ;
>   put(s);
>   new_line;
> 
>   a := prod.code'Address;
>   put( " code field address: " );
>   s := conv ( a ) ;
>   put(s);
>   new_lin
>   ...
> Q1.
> Addresses are not negative.

Never use Unchecked_Conversion unless you exactly know what you are
doing... Address is modular, when bit-wise converted to a *signed* integer
the result is expectedly surprising.

> How do I output a System.Address?

The example above in legal Ada:

with Ada.Text_IO;              use Ada.Text_IO;
with System.Storage_Elements;  use System.Storage_Elements;
with Interfaces.C;             use Interfaces.C;

procedure Test_Fields is
   type Product is record
      Code : int;     -- Use only C-compatible types when you communicate
      Bcode : char; -- to C
      Ccode : char;
      Third : int;
      Descr : char_array (1..10);
      Price : c_float;
   end record;
   pragma Convention (C, Product);
   P : aliased Product;
begin
   Put_Line ("P'Address:" & Integer_Address'Image (To_Integer
(P'Address)));
   Put_Line ("P.Code'Address:" & Integer_Address'Image (To_Integer
(P.Code'Address)));
   Put_Line ("P.Descr'Address:" & Integer_Address'Image (To_Integer
(P.Descr'Address)));
end Test_Fields;

gives:

P'Address: 38207168
P.Code'Address: 38207168
P.Descr'Address: 38207180

> Dmitri:
> Many thanks for showing how to code the generic Get routine. I have
> never used generics or interfaced to C before and it was so long time
> ago I used Ada (where is my walking stick?) so I don't understand it
> well enough.

Ada generic is roughly what C++ calls template.

> Q2.
> What is the effect of aliased in 'Data : aliased Data_Type;'?
> 
> Data is a local variable. I am confused by the aliased keyword, but it
> would seem guidb copies the record into this and then the record value
> is copied once more into final location (X:Product). If so, one copy
> operation is redundant.

"aliased" means "dear compiler, I plan to take pointers (access type) to
this thing." The compiler will reject Data'Access otherwise, because
without your hint it is free to allocate it in a way that Data would have
no valid machine address at all.

> Q3.
> The wrapper:
> procedure getprod (p:out PRODUCT;res:out int) is
> begin
>    result = guidb ( 0 , addrin(p)??? ) ;
> end
> 
> hides the details of calling the C function and returns data to the
> record variable in the calling program if the address carried by the
> formal parameter can be obtained inside the wrapper. Using p'Address
> for the second actual parameter of guidb would probably just give the
> address of the formal (will check when I know how to output a
> System.Address).
> Is it possible to obtain the memory address of the record variable via
> formal parameter p?

In general case no, because see above. However if you declare PRODUCT a
"limited type" it will be passed by reference. You also [worse] can

   procedure getprod (p: access PRODUCT; ...);

BTW, your concern about copying records is absolutely ungrounded.
Especially because you are using ODBC + a relational DBMS! These are so
extraordinary slow, that you will note no difference even if you did
hundreds of copies.

> Q4.
> Would it be easier to implement this if the wrapper was changed to:
> 
> procedure getprod (p: in System.Address; res:out int) is
> begin
>    result = guidb ( 0 , what goes here??? ) ;
> end
> 
> with user calling it as:
> 
>   getprod ( recordvar'Address , result );

The preferences are as follows:

in out >> access >>>>>>>>>>> address

> Q5.
> Host language event handler procedures are stored as an array of
> procedure addresses which is local to guidb. A procedure is called
> indirectly via this array. This was designed for C/C++, but it would
> be nice to use the same or similar mechanism for Ada.
> Is this going to be possible?

Yes, it is possible, you can have an array of access-to-procedure type. But
an OO way is preferable.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



  reply	other threads:[~2010-04-23 14:15 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-04-21 16:43 How to access this package written in C? resander
2010-04-21 17:39 ` Dmitry A. Kazakov
2010-04-22 20:12 ` Björn Persson
2010-04-22 21:12 ` Keith Thompson
2010-04-23 12:58   ` resander
2010-04-23 14:15     ` Dmitry A. Kazakov [this message]
2010-04-23 14:44     ` John B. Matthews
2010-04-23 15:39       ` John B. Matthews
2010-04-26 18:16     ` Robert A Duff
2010-04-26 19:57       ` Keith Thompson
2010-04-26 21:20         ` Maciej Sobczak
2010-04-27  6:52           ` Alex R. Mosteo
2010-04-27 22:29             ` Randy Brukardt
2010-05-03  8:12               ` Alex R. Mosteo
2010-04-27  0:20         ` Robert A Duff
2010-04-27  1:01           ` Keith Thompson
2010-04-27 16:07             ` Robert A Duff
2010-04-27 22:29               ` Randy Brukardt
2010-04-27  1:31           ` Randy Brukardt
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox