From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Interfaces.C + generics: stack overflow
Date: Fri, 24 Mar 2017 23:03:39 +0100
Date: 2017-03-24T23:03:39+01:00 [thread overview]
Message-ID: <ob453p$1dv6$1@gioia.aioe.org> (raw)
In-Reply-To: ejkigvFlkjbU1@mid.individual.net
On 2017-03-24 13:42, hreba wrote:
> generic
> type Real is digits <>;
> type Parameters is private; -- for future use
> package GSL is
>
> gsl_Ex: Exception;
> error_code: Integer; -- of the last operation
>
> type Real_Function is access function (x: Real) return Real;
[...]
Your design looks wrong to me.
An important objection is that the code is not re-entrant. You store
data in the package body during the call.
Another issue is that you forgot C convention for GSL_Function.
If you want to pass an Ada function to the integrator you must use a C
wrapper for it. An alternative would be to use C convention for
Real_Function, but let us put that aside.
Now the Params component is just for this case. What you should do is to
pass a pointer to the Ada function via Params plus parameter for the
function if any. E.g.
type Arguments is record
Func : Real_Function;
Params : Parameters; -- You can use parameters later
end record;
type Arguments_Ptr is access all Arguments;
pragma Convention (C, Arguments_Ptr);
type GSL_Inner_Function is
access function
( x : C.double;
params : Arguments_Ptr
) return C.double;
pragma Convention (C, GSL_Inner_Function);
type GSL_Function is record
func : GSL_Inner_Function;
params : Arguments_Ptr;
end record;
pragma Convention (C, GSL_Function); -- Do not forget this!
function C_Func (X : C.double; Params : Arguments_Ptr)
return C.double;
pragma Convention (C, C_Func);
function C_Func (X : C.double; Params : Arguments_Ptr)
return C.double is
begin -- Params is pointer to Ada function + its parameters
return C.double (Params.Func (Real (x)));
exception
when others => -- You never propagate Ada exceptions from C
return 0.0; -- code! Do tracing here if you want or call
end C_Func; -- Exit() to kill the program
function gsl_integration_qng
( f : in out GSL_Function;
a, b, epsabs, epsrel : C.double;
result, abserr : out C.double;
neval : out C.size_t
) return C.int;
pragma Import (C, gsl_integration_qng, "gsl_integration_qng");
procedure Integration_QNG
( f : Real_Function;
a, b, epsabs, epsrel : Real;
result, abserr : out Real;
neval : out Natural
) is
use type C.int;
Ada_Data : aliased Arguments;
C_Data : GSL_Function :=
(C_Func'Access, Ada_Data'Unchecked_Access);
status : C.int;
res, ae : C.double;
ne : C.size_t;
begin
Ada_Data.Func := f;
status :=
gsl_integration_qng
( C_Data,
C.double (a),
C.double (b),
C.double (epsabs),
C.double (epsrel),
res, ae, ne
);
...
No data stored in the package body.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
next prev parent reply other threads:[~2017-03-24 22:03 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-23 7:43 Interfaces.C + generics: stack overflow hreba
2017-03-23 7:46 ` hreba
2017-03-23 17:45 ` Jeffrey R. Carter
2017-03-24 12:20 ` hreba
2017-03-23 20:03 ` Randy Brukardt
2017-03-24 12:42 ` hreba
2017-03-24 20:13 ` Randy Brukardt
2017-03-24 22:03 ` Dmitry A. Kazakov [this message]
2017-03-25 14:17 ` hreba
2017-03-25 15:21 ` hreba
2017-03-26 22:34 ` Robert Eachus
2017-03-27 7:21 ` Dmitry A. Kazakov
2017-03-30 17:12 ` Robert Eachus
2017-03-25 15:23 ` Dmitry A. Kazakov
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox