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-Google-Thread: 103376,23ca868289d9f0c X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!postnews.google.com!m73g2000cwd.googlegroups.com!not-for-mail From: "cl1" Newsgroups: comp.lang.ada Subject: Re: generic package with procedure paramter gives "not subtype conformant with declaration" Date: 1 Oct 2006 21:31:46 -0700 Organization: http://groups.google.com Message-ID: <1159763506.841048.175930@m73g2000cwd.googlegroups.com> References: <1159651201.121690.130430@b28g2000cwb.googlegroups.com> <1159682538.644835.248030@m7g2000cwm.googlegroups.com> <3UUTg.1003037$084.701942@attbi_s22> <1159738009.962575.108920@i42g2000cwa.googlegroups.com> NNTP-Posting-Host: 66.160.210.89 Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" X-Trace: posting.google.com 1159763512 31047 127.0.0.1 (2 Oct 2006 04:31:52 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Mon, 2 Oct 2006 04:31:52 +0000 (UTC) In-Reply-To: User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X; en) AppleWebKit/418.9 (KHTML, like Gecko) Safari/419.3,gzip(gfe),gzip(gfe) Complaints-To: groups-abuse@google.com Injection-Info: m73g2000cwd.googlegroups.com; posting-host=66.160.210.89; posting-account=MCxsfw0AAABxs2rB6FOIOk-6XLUrvbBM Xref: g2news2.google.com comp.lang.ada:6834 Date: 2006-10-01T21:31:46-07:00 List-Id: Jeffrey R. Carter wrote: > cl1 wrote: > > > > This is a very good concept. Is there a mechanism in ada to allow: > > > > My_Void_Ptr := My_C_Float'Access; > > > > where My_C_Float could be My_New_Type or My_Integer, etc. > > I ask, because my code does this and i was using the System.Address as > > a catch all. Once i store the access in the pointer i no longer need to > > know > > what type it is. I just need the reference to pass to the C code. For > > instance: > > If the access values come from Ada, it gets a bit more complicated. > However, C pointers are convertible from one type to another, IIRC, so > that works for you. You need to declare a convention-C access type for > the type you use, store the 'access in one of those, then unchecked > convert that value to the void pointer type. A generic can make that easier: > > with Ada.Unchecked_Conversion; > ... > type Void_Ptr is ... > ... > generic -- Void_Conversion > type T (<>) is limited private; > package Void_Conversion is > type T_Ptr is access all T; > pragma Convention (C, T_Ptr); > > function To_Void_Ptr is new Ada.Unchecked_Conversion > (Source => T_Ptr, Target => Void_Ptr); > end Void_Conversion; Genius, pure genius! :D Thank you. so now my System.Address becomes Void_Access via: with Ada.Unchecked_Conversion; package General_Conversion type Void is null record; type Void_Access is access all Void; pragma Convention(C, Void_Access); generic type Any_C_Convention_Type (<>) is limited private; package Void_Conversion is type Convert_From_Access is access all Any_C_Convention_Type; pragma Convetion(C, Convert_From_Access); function To_Void_Access is new Ada.Unchecked_Conversion( Source => Convert_From_Access; Target => Void_Access); end General_Conversion; A bit more wordy. But at least it is correct. For anyone who is curious. This crazy code is being implemented so that you can call variable argument c functions. It interfaces with ffcall's avcall which is like, as they describe, av_list in reverse. So far I have the code that autogenerates wrappers for the avcall macros. The code I orginally posted is the code to store all the parameters to the variable argument C function. The process for a user of my packages should be: 1. write a bit of code (8 lines for 1 type, and 1 additional line for each new type) to autogenerate ada and c functions/procedures to interface with ffcall for your types( The Interfaces.C types already have wrappers) 2. Create a wrapper function for the variable argument C function you want to call. This example is missing the recently disscussed Void_Ptr type: package body Example is -- here is your variable argument function procedure My_Var_Args(Item1 : Int; Args : Var_Args) is -- here is the real variable argument c function procedure c_my_var_args; pragma Import(C, c_my_var_args, "my_var_args"); -- here is your return value from your c_my_var_args function Return_Value : Int; -- set Av_Start to the generated av_start wrapper function -- autogenerated with the functions in ffcall.avcallextensions package Av_Start : Av_Start_Access := av_start_foo_ptr; begin -- add your defined argments to the front of Var_Args Prepend(Args, Item1); -- call your function(c_my_var_args) Call(Args, c_my_var_args'Address, Return_Value'Address, av_start_Foo_ptr'Access); -- return your return value return Return_Value; end My_Var_Args; end Example; 3. Then use the new function or procedure like so: My_Var_Args(a, b, Start_Var_Args & p1 & p2 & p3 & pN); The only limitation is that you can pass struct pointers but not structs themselves as parameters. ffcall however has macros for passing structs, so if that were imperative, you could manually make a c function wrapper for those macros and an ada corespondance. which could be used with the rest of my system. I plan on redesigning/reimplementing all instances of System.Address to this new Void_Ptr scheme. Just thought you might like to know what you have been helping with Thanks again. > > Then you can do > > package C_Float_Convert is new Void_Conversions (T => C_Float); > > T_Ptr : constant C_Float_Convert.T_Ptr := My_C_Float'access; > > My_Void_Ptr : Void_Ptr := C_Float_Convert.To_Void_Ptr (T_Ptr); > > > Now that i know that is the rule. I not only understand what was > > causing > > the problem, but why. > > That's usually a good thing. > > -- > Jeff Carter > "Monsieur Arthur King, who has the brain of a duck, you know." > Monty Python & the Holy Grail > 09