* generic package with procedure paramter gives "not subtype conformant with declaration" @ 2006-09-30 21:20 cl1 2006-10-01 1:27 ` Jeffrey R. Carter 2006-10-01 7:18 ` Simon Wright 0 siblings, 2 replies; 16+ messages in thread From: cl1 @ 2006-09-30 21:20 UTC (permalink / raw) I don't understand why i can't pass Av_Param to the generic package (in test_call_avcall_register_type.adb) and have its 'Access attribute used in Concat (the offending code in avcall-register_type.adb)? i'm getting the following error: $ gnatmake -gnatc ./Ada_Source/test_avcall_register_type.adb gcc -c -I./Ada_Source/ -gnatc -I- ./Ada_Source/test_avcall_register_type.adb gcc -c -I./Ada_Source/ -gnatc -I- ./Ada_Source/avcall.adb gcc -c -I./Ada_Source/ -gnatc -I- ./Ada_Source/avcall-register_type.adb avcall-register_type.adb:13:34: not subtype conformant with declaration at avcall.ads:37 avcall-register_type.adb:13:34: formal subprograms not allowed gnatmake: "./Ada_Source/avcall-register_type.adb" compilation error on this code: <avcall.ads> with System; use System; package avcall is -- <snip> ---------------------------------------------------------------------------- -- This exeption is thrown when you try to add more than Max_Args to the -- Var_Args type Max_Arg_Limit_Surpassed : exception; ---------------------------------------------------------------------------- -- The maximum number of arguments that can be used by avcall Max_Args : constant := 50; ---------------------------------------------------------------------------- -- this is the number of arguments in the Var_Args list subtype Arg_Count is Natural range 0..Max_Args; ---------------------------------------------------------------------------- -- This is the range used by the Var_Args list subtype Arg_Range is Natural range 1..Max_Args; ---------------------------------------------------------------------------- -- this represents an argument held in the Arg_List type Argument is tagged record ------------------------------------------------------------------------ -- This holds the correct av_<type> c function to call. Av_Param : access procedure(Av_List : System.Address; Value : System.Address); ------------------------------------------------------------------------ -- This holds the address of the value. This is assigned by the child -- type of this type in the Register_Type package during the -- Initialize procedure call of the child type. Value_Address : System.Address; ------------------------------------------------------------------------ end record; ---------------------------------------------------------------------------- -- This type is used by the Var_Args type to hold all of the arguments. type Arg_List is array(Arg_Range range <>) of Argument; ---------------------------------------------------------------------------- -- This is the Var_Args type. This is used to hold all of the arguments to -- the c function (the ... and all the arguments before that). -- The Start_Var_Args, "&", and Prepend methods and functions are used to -- add arguments to Var_Args. type Var_Args is record ------------------------------------------------------------------------ -- this is a pointer to the c data type that makes this work. -- Av_List_Malloc and Av_List_Free (defined in the body) are used to -- obtain the reference and free it respectivly Av_List : System.Address; ------------------------------------------------------------------------ -- This is the number of arguments in the Arg_List Count : access Arg_Count; ------------------------------------------------------------------------ -- This is what holds all of the arguments. List : access Arg_List := new Arg_List(Arg_Range'Range); ------------------------------------------------------------------------ end record; ---------------------------------------------------------------------------- -- <snip> end avcall; <avcall-register_type.ads> with System.Address_To_Access_Conversions; with System; use System; -------------------------------------------------------------------------------- generic type Any_Type is private; with procedure Av_Param_Instance(AList : System.Address; Value : System.Address); package avcall.register_type is ---------------------------------------------------------------------------- package Any_Type_Conversion is new System.Address_To_Access_Conversions(Any_Type); ---------------------------------------------------------------------------- type Argument_Instance is new Argument with record Instance_Value : Any_Type_Conversion.Object_Pointer; end record; ---------------------------------------------------------------------------- function Concat(AList : Var_Args; Arg : Any_Type) return Var_Args; ---------------------------------------------------------------------------- end avcall.register_type; <avcall-register_type.adb> package body avcall.register_type is ---------------------------------------------------------------------------- -- Adds the value in Arg to the next Var_Args.List function Concat(AList : Var_Args; Arg : Any_Type) return Var_Args is Info : Argument_Instance; begin Info.Av_Param := Av_Param_Instance'Access; Info.Instance_Value.all := Arg; Info.Value_Address := Any_Type_Conversion.To_Address(Info.Instance_Value); AList.Count.all := AList.Count.all + 1; AList.List(AList.Count.all) := Argument(Info); return AList; end Concat; ---------------------------------------------------------------------------- end avcall.register_type; <test_avcall_register_type.adb> with avcall; use avcall; with avcall.register_type; with Ada.Text_IO; use Ada.Text_IO; with System; use System; -------------------------------------------------------------------------------- procedure test_avcall_register_type is procedure Av_Param(AList : System.Address; Value : System.Address) is begin null; end Av_Param; package Int_Registered is new avcall.register_type(Integer, Av_Param); begin Put_Line("FOO"); end test_avcall_register_type; <offending code> --avcall-register_type.adb:13:34: not subtype conformant with declaration at avcall.ads:37 --avcall-register_type.adb:13:34: formal subprograms not allowed Info.Av_Param := Av_Param_Instance'Access; <end of code post> I don't understand why i can't pass Av_Param to the generic package (in test_call_avcall_register_type.adb) and have its 'Access attribute used in Concat (the offending code in avcall-register_type.adb)? ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: generic package with procedure paramter gives "not subtype conformant with declaration" 2006-09-30 21:20 generic package with procedure paramter gives "not subtype conformant with declaration" cl1 @ 2006-10-01 1:27 ` Jeffrey R. Carter 2006-10-01 6:02 ` cl1 2006-10-01 7:18 ` Simon Wright 1 sibling, 1 reply; 16+ messages in thread From: Jeffrey R. Carter @ 2006-10-01 1:27 UTC (permalink / raw) cl1 wrote: > --avcall-register_type.adb:13:34: not subtype conformant with > declaration at avcall.ads:37 > --avcall-register_type.adb:13:34: formal subprograms not allowed > Info.Av_Param := Av_Param_Instance'Access; > <end of code post> You seem to have cut things down a bit too much. avcall.ads has no line 37. If you're going to cut things down this much, please post messages that result from compiling the cut-down code. You shouldn't use System.Address to interface to C. Use a convention-C access type instead. > I don't understand why i can't pass Av_Param to the generic package (in > test_call_avcall_register_type.adb) and have its 'Access attribute used > in Concat (the offending code in avcall-register_type.adb)? You don't say what version of GNAT you're using. However, I suspect what you're running into is an accessibility control problem. You can't store the generic formal procedure's 'access because the compiler can't be sure that the life of the access value is no longer than the life of the actual procedure. -- Jeff Carter "Sir Lancelot saves Sir Gallahad from almost certain temptation." Monty Python & the Holy Grail 69 ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: generic package with procedure paramter gives "not subtype conformant with declaration" 2006-10-01 1:27 ` Jeffrey R. Carter @ 2006-10-01 6:02 ` cl1 2006-10-01 19:43 ` Jeffrey R. Carter 0 siblings, 1 reply; 16+ messages in thread From: cl1 @ 2006-10-01 6:02 UTC (permalink / raw) Jeffrey R. Carter wrote: > cl1 wrote: > > --avcall-register_type.adb:13:34: not subtype conformant with > > declaration at avcall.ads:37 > > --avcall-register_type.adb:13:34: formal subprograms not allowed > > Info.Av_Param := Av_Param_Instance'Access; > > <end of code post> > > You seem to have cut things down a bit too much. avcall.ads has no line > 37. If you're going to cut things down this much, please post messages > that result from compiling the cut-down code. that is why i posted the very last section called <offending code> so you could see which line it was. I didn't think to compile the cut down code. I appologize. line 37 is lines 23 and 24 in the snippet of avcall.ads > > You shouldn't use System.Address to interface to C. Use a convention-C > access type instead. I understand the reason for using access types with convention C, but that will not work for this situation. Everywhere i have used System.Address the code does not know, does not care what type or subprogram signature is stored there, and will not use it other than to pass it along to some c function that knows what to do with it. If there is a System.Address being used that doesn't fit that, then it is a bug. I also choose not to use 'type void_ptr is new System.Address;' specifically becuase that is what System.Address is. Also someone once told me that writing code that requires the user to with System; alerts the user that the code is system dependant. I like that idea. This code is system dependant. By that, I mean it is dependant on the processor and in some situations the operating system, not the compiler implementation. Well to be honest the Ada code isn't but the C code it interfaces with is (ffcall's avcall). > > > I don't understand why i can't pass Av_Param to the generic package (in > > test_call_avcall_register_type.adb) and have its 'Access attribute used > > in Concat (the offending code in avcall-register_type.adb)? > > You don't say what version of GNAT you're using. i'm using GPS which has gcc version 3.4.6 on mac os x 10.4.8 > However, I suspect what > you're running into is an accessibility control problem. You can't store > the generic formal procedure's 'access because the compiler can't be > sure that the life of the access value is no longer than the life of the > actual procedure. I agree with you. However, I am confused about this. The procedure could be declared anywhere. How does the compiler know what scope the procedure that is supplied to the generic package is in? I mean can it ever know? If not, that means there is no foreseeable fix to this issue from my point of view. > > -- > Jeff Carter > "Sir Lancelot saves Sir Gallahad from almost certain temptation." > Monty Python & the Holy Grail > 69 ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: generic package with procedure paramter gives "not subtype conformant with declaration" 2006-10-01 6:02 ` cl1 @ 2006-10-01 19:43 ` Jeffrey R. Carter 2006-10-01 21:26 ` cl1 0 siblings, 1 reply; 16+ messages in thread From: Jeffrey R. Carter @ 2006-10-01 19:43 UTC (permalink / raw) cl1 wrote: > > I understand the reason for using access types with convention C, but > that > will not work for this situation. Everywhere i have used System.Address > the code > does not know, does not care what type or subprogram signature is > stored there, and will > not use it other than to pass it along to some c function that knows > what to do with it. If > there is a System.Address being used that doesn't fit that, then it is > a bug. I also choose > not to use 'type void_ptr is new System.Address;' specifically becuase > that is what > System.Address is. Also someone once told me that writing code that > requires the user > to with System; alerts the user that the code is system dependant. I > like that idea. This > code is system dependant. By that, I mean it is dependant on the > processor and in > some situations the operating system, not the compiler implementation. > Well to be > honest the Ada code isn't but the C code it interfaces with is > (ffcall's avcall). The problem is that System.Address is not guaranteed to be the same as a C pointer, so using it to interface with C makes your code compiler dependent. In all versions of GNAT that I've used and bothered to check, System.Address has been the same as a C pointer, but that could change at any time. For types, any convention-C access type will work for a void pointer when the values come from C and are never dereferenced by the Ada. I generally use "access all Integer" for that case, though some people prefer to have a void type to designate: type Void is null record; type Void_Ptr is access all Void; pragma Convention (C, Void_Ptr); Since values of Void_Ptr are never dereferenced, the designated type doesn't matter. For subprograms, it's more complicated because you have to match the subprogram parameter and return type profile. In your case, though (IIRC), the subprograms all have the same profile (that of your generic formal subprogram), so the use of a convention-C access type seems to be possible. > i'm using GPS which has gcc version 3.4.6 on mac os x 10.4.8 GPS is an IDE, not a compiler, but gcc 3.4.6 is; it's an Ada-95 compiler. The compiler version is of interest because Ada 95's accessibility rules differ from Ada 0X's. > I agree with you. > However, I am confused about this. The procedure could be declared > anywhere. How > does the compiler know what scope the procedure that is supplied to the > generic package is in? I mean can it ever know? If not, that means > there > is no foreseeable fix to this issue from my point of view. The compiler can't know the scope of the actual procedure in general; that's why you can never store the 'access of a generic formal procedure. The language assumes the worst case for safety. -- Jeff Carter "Monsieur Arthur King, who has the brain of a duck, you know." Monty Python & the Holy Grail 09 ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: generic package with procedure paramter gives "not subtype conformant with declaration" 2006-10-01 19:43 ` Jeffrey R. Carter @ 2006-10-01 21:26 ` cl1 2006-10-01 23:17 ` tmoran 2006-10-02 3:24 ` Jeffrey R. Carter 0 siblings, 2 replies; 16+ messages in thread From: cl1 @ 2006-10-01 21:26 UTC (permalink / raw) Jeffrey R. Carter wrote: > cl1 wrote: > > <snip> > > The problem is that System.Address is not guaranteed to be the same as a > C pointer, so using it to interface with C makes your code compiler > dependent. In all versions of GNAT that I've used and bothered to check, > System.Address has been the same as a C pointer, but that could change > at any time. I did not know this. I am forever learning, it seems. > > For types, any convention-C access type will work for a void pointer > when the values come from C and are never dereferenced by the Ada. I > generally use "access all Integer" for that case, though some people > prefer to have a void type to designate: > > type Void is null record; > type Void_Ptr is access all Void; > pragma Convention (C, Void_Ptr); 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: package avcall is type Argument is record Value_Address : System.Address; end record; end avcall; generic type Any_Type is private; package avcall.register_type package Any_Type_Conversion is new System.Address_To_Access_Conversions(Any_Type); type Argument_Instance is record Instance_Value : Any_Type_Conversion.Object_Pointer; end record; function Concat(AList : Var_Args; Arg : Any_Type) return Var_Args is Info : Argument_Instance; begin Info.Instance_Value := Arg; Info.Value_Address := Any_Type_Conversion.To_Address(Info.Instance_Value); return AList; end; end avcall.register_type; This is how i'm currently doing things. How would i change my Argument.Value_Address from System.Address type to something like the Void_Ptr type you proposed? So that i can change: Info.Value_Address := Any_Type_Conversion.To_Address(Info.Instance_Value); to work with the Void_Ptr type. > > Since values of Void_Ptr are never dereferenced, the designated type > doesn't matter. > > For subprograms, it's more complicated because you have to match the > subprogram parameter and return type profile. In your case, though > (IIRC), the subprograms all have the same profile (that of your generic > formal subprogram), so the use of a convention-C access type seems to be > possible. > > > i'm using GPS which has gcc version 3.4.6 on mac os x 10.4.8 > > GPS is an IDE, not a compiler, but gcc 3.4.6 is; it's an Ada-95 > compiler. The compiler version is of interest because Ada 95's > accessibility rules differ from Ada 0X's. > > > I agree with you. > > However, I am confused about this. The procedure could be declared > > anywhere. How > > does the compiler know what scope the procedure that is supplied to the > > generic package is in? I mean can it ever know? If not, that means > > there > > is no foreseeable fix to this issue from my point of view. > > The compiler can't know the scope of the actual procedure in general; > that's why you can never store the 'access of a generic formal > procedure. The language assumes the worst case for safety. to quote another post in this thread: -And you wanted to do Av_Param_Instance'Access inside the generic? -That won't work, because the compiler can't check the rules about -X'Access, because it doesn't know enough about the actual parameter -passed to Av_Param_Instance. The accessibility rules come to mind. -Also, the fact that you can't do X'Access if X is intrinsic Now that i know that is the rule. I not only understand what was causing the problem, but why. > > -- > Jeff Carter > "Monsieur Arthur King, who has the brain of a duck, you know." > Monty Python & the Holy Grail > 09 ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: generic package with procedure paramter gives "not subtype conformant with declaration" 2006-10-01 21:26 ` cl1 @ 2006-10-01 23:17 ` tmoran 2006-10-02 4:46 ` cl1 2006-10-02 3:24 ` Jeffrey R. Carter 1 sibling, 1 reply; 16+ messages in thread From: tmoran @ 2006-10-01 23:17 UTC (permalink / raw) > > For types, any convention-C access type will work for a void pointer > > when the values come from C and are never dereferenced by the Ada. > ... > 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. Maybe I'm not understanding but if the values come from C and are never used by Ada, but merely passed on to other calls on C, why not just declare them as type C_Param is new Interfaces.Unsigned_32; and treat them in Ada as a black box, size 32, content unknown. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: generic package with procedure paramter gives "not subtype conformant with declaration" 2006-10-01 23:17 ` tmoran @ 2006-10-02 4:46 ` cl1 0 siblings, 0 replies; 16+ messages in thread From: cl1 @ 2006-10-02 4:46 UTC (permalink / raw) tmoran@acm.org wrote: > > > For types, any convention-C access type will work for a void pointer > > > when the values come from C and are never dereferenced by the Ada. > > ... > > 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. > Maybe I'm not understanding but if the values come from C and are > never used by Ada, but merely passed on to other calls on C, why not > just declare them as > type C_Param is new Interfaces.Unsigned_32; > and treat them in Ada as a black box, size 32, content unknown. The values come from ada. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: generic package with procedure paramter gives "not subtype conformant with declaration" 2006-10-01 21:26 ` cl1 2006-10-01 23:17 ` tmoran @ 2006-10-02 3:24 ` Jeffrey R. Carter 2006-10-02 4:31 ` cl1 1 sibling, 1 reply; 16+ messages in thread From: Jeffrey R. Carter @ 2006-10-02 3:24 UTC (permalink / raw) 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; 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 ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: generic package with procedure paramter gives "not subtype conformant with declaration" 2006-10-02 3:24 ` Jeffrey R. Carter @ 2006-10-02 4:31 ` cl1 2006-10-02 7:17 ` Alex R. Mosteo 2006-10-02 20:04 ` Jeffrey R. Carter 0 siblings, 2 replies; 16+ messages in thread From: cl1 @ 2006-10-02 4:31 UTC (permalink / raw) 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 ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: generic package with procedure paramter gives "not subtype conformant with declaration" 2006-10-02 4:31 ` cl1 @ 2006-10-02 7:17 ` Alex R. Mosteo 2006-10-02 20:04 ` Jeffrey R. Carter 1 sibling, 0 replies; 16+ messages in thread From: Alex R. Mosteo @ 2006-10-02 7:17 UTC (permalink / raw) cl1 wrote: > > 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. You can see an example of a binding using this technique in http://sourceforge.net/projects/ada-player Therein are types coming from the C and Ada side being used in calls to the C side. It is an Ada-C binding for the robotic controller Player: http://playerstage.sf.net ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: generic package with procedure paramter gives "not subtype conformant with declaration" 2006-10-02 4:31 ` cl1 2006-10-02 7:17 ` Alex R. Mosteo @ 2006-10-02 20:04 ` Jeffrey R. Carter 2006-10-03 18:49 ` cl1 1 sibling, 1 reply; 16+ messages in thread From: Jeffrey R. Carter @ 2006-10-02 20:04 UTC (permalink / raw) cl1 wrote: > > Genius, pure genius! :D Thanks. More accurately, experience and a desire to be portable whenever possible. > 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: I guess you have to handle any number of arguments. For specific or commonly used cases, you can declare multiple Ada subprograms, each with different numbers or types of parameters, that all pragma Import the same C function. Since you're generating packages for your clients, perhaps it would be easier on your clients if you generated such specific subprograms for them. For example: package C renames Interfaces.C; procedure Print_Str (Format : in C.Char_Array; Str : in C.Char_Array); pragma Import (C, Print_Str, "printf"); procedure Print_Int (Format : in C.Char_Array; Num : in C.Int); pragma Import (C, Print_Int, "printf"); procedure Print_Str_Int (Format : in C.Char_Array; Str : in C.Char_Array; Num : in C.Int); pragma Import (C, Print_Str_Int, "printf"); -- Jeff Carter "It's all right, Taggart. Just a man and a horse being hung out there." Blazing Saddles 34 ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: generic package with procedure paramter gives "not subtype conformant with declaration" 2006-10-02 20:04 ` Jeffrey R. Carter @ 2006-10-03 18:49 ` cl1 0 siblings, 0 replies; 16+ messages in thread From: cl1 @ 2006-10-03 18:49 UTC (permalink / raw) Jeffrey R. Carter wrote: > cl1 wrote: > > > > Genius, pure genius! :D > > Thanks. More accurately, experience and a desire to be portable whenever > possible. > > > 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: > > I guess you have to handle any number of arguments. For specific or > commonly used cases, you can declare multiple Ada subprograms, each with > different numbers or types of parameters, that all pragma Import the > same C function. Since you're generating packages for your clients, > perhaps it would be easier on your clients if you generated such > specific subprograms for them. > > For example: > > package C renames Interfaces.C; > > procedure Print_Str (Format : in C.Char_Array; Str : in C.Char_Array); > pragma Import (C, Print_Str, "printf"); > > procedure Print_Int (Format : in C.Char_Array; Num : in C.Int); > pragma Import (C, Print_Int, "printf"); > > procedure Print_Str_Int (Format : in C.Char_Array; > Str : in C.Char_Array; > Num : in C.Int); > pragma Import (C, Print_Str_Int, "printf"); > > -- > Jeff Carter > "It's all right, Taggart. Just a man and a horse being hung out there." > Blazing Saddles > 34 If my information serves me correctly, Ada doesn't define what happens when you import variable argument functions like that. It recomends that the only sure way is to write a c function wrapper that calls the variable argument function. The cool thing about ffcall's avcall is that I only have to write 2 wrapper functions for each type. One for the case where it is a return value, and one where it is an argument to the function. That is what my autogeneration code does. It writes those wrapper functions, and the coresponding ada procedures and their pramga import. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: generic package with procedure paramter gives "not subtype conformant with declaration" 2006-09-30 21:20 generic package with procedure paramter gives "not subtype conformant with declaration" cl1 2006-10-01 1:27 ` Jeffrey R. Carter @ 2006-10-01 7:18 ` Simon Wright 2006-10-01 19:42 ` cl1 1 sibling, 1 reply; 16+ messages in thread From: Simon Wright @ 2006-10-01 7:18 UTC (permalink / raw) Put this somewhere (in package avcall I guess) type Av_Param_Access is access procedure (AList : System.Address; Value : System.Address); then generic type Any_Type is private; Av_Param_Instance : Av_Param_Access; package avcall.register_type is Compiles OK (same environment as you), whether it is correct and whether it works are of course different matters. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: generic package with procedure paramter gives "not subtype conformant with declaration" 2006-10-01 7:18 ` Simon Wright @ 2006-10-01 19:42 ` cl1 2006-10-01 20:18 ` Robert A Duff 0 siblings, 1 reply; 16+ messages in thread From: cl1 @ 2006-10-01 19:42 UTC (permalink / raw) Simon Wright wrote: > Put this somewhere (in package avcall I guess) > > type Av_Param_Access > is access procedure (AList : System.Address; > Value : System.Address); > > then > > generic > type Any_Type is private; > Av_Param_Instance : Av_Param_Access; > package avcall.register_type is > > Compiles OK (same environment as you), whether it is correct and > whether it works are of course different matters. Thank you very much. It fixed the problem, but i do not understand why: with procedure Av_Param_Instance(Av_List, Value : System.Address); does not work. If anyone knows why, I would be greatfull for an explination. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: generic package with procedure paramter gives "not subtype conformant with declaration" 2006-10-01 19:42 ` cl1 @ 2006-10-01 20:18 ` Robert A Duff 2006-10-01 21:32 ` cl1 0 siblings, 1 reply; 16+ messages in thread From: Robert A Duff @ 2006-10-01 20:18 UTC (permalink / raw) "cl1" <charles.w.lambert@gmail.com> writes: > Thank you very much. > It fixed the problem, but i do not understand why: > with procedure Av_Param_Instance(Av_List, Value : System.Address); > does not work. If anyone knows why, I would be greatfull for an > explination. And you wanted to do Av_Param_Instance'Access inside the generic? That won't work, because the compiler can't check the rules about X'Access, because it doesn't know enough about the actual parameter passed to Av_Param_Instance. The accessibility rules come to mind. Also, the fact that you can't do X'Access if X is intrinsic. - Bob ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: generic package with procedure paramter gives "not subtype conformant with declaration" 2006-10-01 20:18 ` Robert A Duff @ 2006-10-01 21:32 ` cl1 0 siblings, 0 replies; 16+ messages in thread From: cl1 @ 2006-10-01 21:32 UTC (permalink / raw) Robert A Duff wrote: > "cl1" <charles.w.lambert@gmail.com> writes: > > > Thank you very much. > > It fixed the problem, but i do not understand why: > > with procedure Av_Param_Instance(Av_List, Value : System.Address); > > does not work. If anyone knows why, I would be greatfull for an > > explination. > > And you wanted to do Av_Param_Instance'Access inside the generic? > > That won't work, because the compiler can't check the rules about > X'Access, because it doesn't know enough about the actual parameter > passed to Av_Param_Instance. The accessibility rules come to mind. > Also, the fact that you can't do X'Access if X is intrinsic. Now that I know that is the rule, everything is clear once again. I had made the assumption that it would work based on the definition in the arm on how generic packages are elaborated. I love how Ada is so well defined. Now if i could just memorize the ARM ... :-D > > - Bob ^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2006-10-03 18:49 UTC | newest] Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2006-09-30 21:20 generic package with procedure paramter gives "not subtype conformant with declaration" cl1 2006-10-01 1:27 ` Jeffrey R. Carter 2006-10-01 6:02 ` cl1 2006-10-01 19:43 ` Jeffrey R. Carter 2006-10-01 21:26 ` cl1 2006-10-01 23:17 ` tmoran 2006-10-02 4:46 ` cl1 2006-10-02 3:24 ` Jeffrey R. Carter 2006-10-02 4:31 ` cl1 2006-10-02 7:17 ` Alex R. Mosteo 2006-10-02 20:04 ` Jeffrey R. Carter 2006-10-03 18:49 ` cl1 2006-10-01 7:18 ` Simon Wright 2006-10-01 19:42 ` cl1 2006-10-01 20:18 ` Robert A Duff 2006-10-01 21:32 ` cl1
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox