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=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!news.eternal-september.org!feeder.eternal-september.org!aioe.org!.POSTED!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: Interfaces.C + generics: stack overflow Date: Fri, 24 Mar 2017 23:03:39 +0100 Organization: Aioe.org NNTP Server Message-ID: References: NNTP-Posting-Host: BYuA7L7MRjuLLjcoGHOBxw.user.gioia.aioe.org Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit X-Complaints-To: abuse@aioe.org User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:45.0) Gecko/20100101 Thunderbird/45.8.0 X-Notice: Filtered by postfilter v. 0.8.2 Xref: news.eternal-september.org comp.lang.ada:46451 Date: 2017-03-24T23:03:39+01:00 List-Id: 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