From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,74bc23dcb20218db X-Google-NewGroupId: yes X-Google-Attributes: gida07f3367d7,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news4.google.com!feeder2.cambriumusenet.nl!feed.tweaknews.nl!195.71.90.67.MISMATCH!news.unit0.net!noris.net!newsfeed.arcor.de!newsspool4.arcor-online.net!news.arcor.de.POSTED!not-for-mail From: "Dmitry A. Kazakov" Subject: Re: How to access this package written in C? Newsgroups: comp.lang.ada User-Agent: 40tude_Dialog/2.0.15.1 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Reply-To: mailbox@dmitry-kazakov.de Organization: cbb software GmbH References: <4e9d2aaf-c0a6-4798-b838-8f5b7c4a39d1@k33g2000yqc.googlegroups.com> Date: Fri, 23 Apr 2010 16:15:31 +0200 Message-ID: <5h5csoxoxqv7.1i6yifddkcfhi$.dlg@40tude.net> NNTP-Posting-Date: 23 Apr 2010 16:15:31 CEST NNTP-Posting-Host: 74e8db5e.newsspool2.arcor-online.net X-Trace: DXC=UFHN0>0@BblPXlQ;h]GTMdA9EHlD;3Ycb4Fo<]lROoRa8kF 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