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.9 required=5.0 tests=BAYES_00,FORGED_GMAIL_RCVD, FREEMAIL_FROM autolearn=no autolearn_force=no version=3.4.4 X-Received: by 2002:ac8:7b27:: with SMTP id l7mr6764780qtu.283.1588747366105; Tue, 05 May 2020 23:42:46 -0700 (PDT) X-Received: by 2002:a9d:5cc1:: with SMTP id r1mr4876608oti.329.1588747365714; Tue, 05 May 2020 23:42:45 -0700 (PDT) Path: eternal-september.org!reader01.eternal-september.org!feeder.eternal-september.org!aioe.org!peer03.ams4!peer.am4.highwinds-media.com!peer02.iad!feed-me.highwinds-media.com!news.highwinds-media.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail Newsgroups: comp.lang.ada Date: Tue, 5 May 2020 23:42:45 -0700 (PDT) In-Reply-To: Complaints-To: groups-abuse@google.com Injection-Info: google-groups.googlegroups.com; posting-host=185.34.132.200; posting-account=Srm5lQoAAAAEMX9rv2ilEKR6FDPapmSq NNTP-Posting-Host: 185.34.132.200 References: User-Agent: G2/1.0 MIME-Version: 1.0 Message-ID: <728c5319-5f4f-4f21-9d71-cc9c12ed6016@googlegroups.com> Subject: Re: How can one record component be local and another not? From: Mark Lorenzen Injection-Date: Wed, 06 May 2020 06:42:46 +0000 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Received-Bytes: 4489 X-Received-Body-CRC: 2098057897 Xref: reader01.eternal-september.org comp.lang.ada:58607 Date: 2020-05-05T23:42:45-07:00 List-Id: On Tuesday, May 5, 2020 at 7:17:42 PM UTC+2, hreba wrote: > On 5/5/20 5:45 PM, Jeffrey R. Carter wrote: > > On 5/5/20 1:04 PM, hreba wrote: > >> > >> (The reason for the above construction is the need to pass a pointer= =20 > >> to a C library function.) > >=20 > > Most likely you do not need to pass a pointer to your C function. For= =20 > > example, given the C function > >=20 > > void f (int* i); > >=20 > > You can do > >=20 > > procedure F (I : in out Interfaces.C.int) with Import, Convention =3D> = C,=20 > > ...; > >=20 > > and the compiler will call the C function correctly. > >=20 >=20 > It is more complicated, unfortunately. I got >=20 > type gsl_odeiv2_system is record > c_function : access function > (arg1 : double; > arg2 : access double; > arg3 : access double; > arg4 : System.Address) return int; --=20 > /usr/include/gsl/gsl_odeiv2.h:58 > jacobian : access function > (arg1 : double; > arg2 : access double; > arg3 : access double; > arg4 : access double; > arg5 : System.Address) return int; --=20 > /usr/include/gsl/gsl_odeiv2.h:60 > dimension : aliased size_t; -- /usr/include/gsl/gsl_odeiv2.h:61 > params : System.Address; -- /usr/include/gsl/gsl_odeiv2.h:62 > end record; > pragma Convention (C_Pass_By_Copy, gsl_odeiv2_system); --=20 > /usr/include/gsl/gsl_odeiv2.h:64 >=20 > and I have to pass a variable > sys: access gsl_odeiv2_system > to the initialization function of that C library, and the >=20 > params: System.Address; >=20 > component in the record, which internally is then passed to c_function()= =20 > and jacobian(), posed the problem. >=20 > --=20 > Frank Hrebabetzky, Kronach +49 / 9261 / 950 0565 You need to step back and try to get an overview of what you are trying to = achieve - not blindly copy some low-level C construct. Figure out why those= C functions take parameters of an access type. Are they in/out or out para= meters? Then define the Ada equivalent of those function access types e.g: type C_Function_Access is access function (Arg1 : double; Arg2 : in out double; Arg3 : in out double; Arg= 4 : in System.Address) return int with Convention =3D> C; Note that in Ada 2012 functions are unfortunately allowed to have in/out-mo= de and out-mode parameters. In previous revisions, functions were only allo= wed to have in-mode parameters. As explained by Jeffrey R. Carter above, Convention =3D> C guarantees that = in/out-mode and out-mode parameters are passed by value. Your record type then becomes something like: type GSL_Odeiv2_System is record C_Function : C_Function_Access; ... end record with Convention C_Pass_By_Copy; You are trying to create an Ada interface to C, but you are dragging the lo= w-level nature of C into your Ada. When you encounter access types and addr= esses in Ada, then step back and try to get an overview of what needs to be= achieved - not how it is done in C and thus mechanically copied in the aut= o-generated Ada code. Regards, Mark L