comp.lang.ada
 help / color / mirror / Atom feed
From: Mark Lorenzen <mark.lorenzen@gmail.com>
Subject: Re: How can one record component be local and another not?
Date: Tue, 5 May 2020 23:42:45 -0700 (PDT)
Date: 2020-05-05T23:42:45-07:00	[thread overview]
Message-ID: <728c5319-5f4f-4f21-9d71-cc9c12ed6016@googlegroups.com> (raw)
In-Reply-To: <hhdldkFin5dU1@mid.individual.net>

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 
> >> to a C library function.)
> > 
> > Most likely you do not need to pass a pointer to your C function. For 
> > example, given the C function
> > 
> > void f (int* i);
> > 
> > You can do
> > 
> > procedure F (I : in out Interfaces.C.int) with Import, Convention => C, 
> > ...;
> > 
> > and the compiler will call the C function correctly.
> > 
> 
> It is more complicated, unfortunately. I got
> 
>     type gsl_odeiv2_system is record
>        c_function : access function
>             (arg1 : double;
>              arg2 : access double;
>              arg3 : access double;
>              arg4 : System.Address) return int;  -- 
> /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;  -- 
> /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);  -- 
> /usr/include/gsl/gsl_odeiv2.h:64
> 
> and I have to pass a variable
>     sys: access gsl_odeiv2_system
> to the initialization function of that C library, and the
> 
>    params: System.Address;
> 
> component in the record, which internally is then passed to c_function() 
> and jacobian(), posed the problem.
> 
> -- 
> 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 parameters? 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; Arg4 : in System.Address) return int with Convention => C;

Note that in Ada 2012 functions are unfortunately allowed to have in/out-mode and out-mode parameters. In previous revisions, functions were only allowed to have in-mode parameters.

As explained by Jeffrey R. Carter above, Convention => 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 low-level nature of C into your Ada. When you encounter access types and addresses 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 auto-generated Ada code.

Regards,
Mark L

  parent reply	other threads:[~2020-05-06  6:42 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-05 11:04 How can one record component be local and another not? hreba
2020-05-05 11:33 ` AdaMagica
2020-05-05 11:38   ` AdaMagica
2020-05-05 12:59   ` hreba
2020-05-05 13:19     ` J-P. Rosen
2020-05-05 13:37     ` Jere
2020-05-05 14:28       ` hreba
2020-05-05 15:18         ` AdaMagica
2020-05-05 14:32   ` hreba
2020-05-05 11:43 ` AdaMagica
2020-05-05 12:55   ` hreba
2020-05-05 11:46 ` Simon Wright
2020-05-05 13:07   ` hreba
2020-05-05 17:00     ` Dmitry A. Kazakov
2020-05-05 11:48 ` Niklas Holsti
2020-05-05 13:44   ` hreba
2020-05-05 15:45 ` Jeffrey R. Carter
2020-05-05 17:17   ` hreba
2020-05-05 19:08     ` Niklas Holsti
2020-05-06 19:31       ` hreba
2020-05-09 19:43         ` Niklas Holsti
2020-05-10 15:10           ` hreba
2020-05-05 19:19     ` Jere
2020-05-06  6:42     ` Mark Lorenzen [this message]
2020-05-06  8:26       ` Simon Wright
2020-05-06  8:33         ` Mark Lorenzen
2020-05-05 17:32 ` hreba
2020-05-05 19:04   ` Niklas Holsti
2020-05-05 20:11     ` Niklas Holsti
2020-05-06 13:13       ` hreba
2020-05-06 17:30   ` Niklas Holsti
2020-05-06 18:28     ` Jere
2020-05-06 19:09       ` Niklas Holsti
2020-05-07  9:07     ` J-P. Rosen
2020-05-07 10:15       ` Niklas Holsti
2020-05-07 13:00         ` Egil H H
2020-05-07 13:25         ` Simon Wright
2020-05-07 10:31       ` Stefan.Lucks
2020-05-07 11:58         ` J-P. Rosen
replies disabled

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