* Calling Ada proceedures from a C program @ 1999-05-20 0:00 Jason LaPenta 1999-05-20 0:00 ` Gautier ` (3 more replies) 0 siblings, 4 replies; 11+ messages in thread From: Jason LaPenta @ 1999-05-20 0:00 UTC (permalink / raw) Hello, I have a linking/binding question. I'm trying to call an Ada proc. from a C program. Something like... extern void __test( void ); // Ada proc test in a file called test.adb with ada defination in test.ads int main() { __test(); return 1; } I'm compiling the test.ads and the main.C to object code and then trying to link by using gcc -o test.o main.o The originol proc. is test (w/out the two underscores). I haven't been able to find any examples of doing this sort of thing, so if you know of any on the web or otherwise it would help to point me in the right direction. thanks jason lapenta@orca.ds.boeing.com ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Calling Ada proceedures from a C program 1999-05-20 0:00 Calling Ada proceedures from a C program Jason LaPenta @ 1999-05-20 0:00 ` Gautier 1999-05-20 0:00 ` David C. Hoos, Sr. ` (2 subsequent siblings) 3 siblings, 0 replies; 11+ messages in thread From: Gautier @ 1999-05-20 0:00 UTC (permalink / raw) To: Jason LaPenta > The originol proc. is test (w/out the two underscores). I haven't been > able to find any examples of doing this sort of thing, so if you know of > any on the web or otherwise it would help to point me in the right > direction. This is surely because the natural mixing is the reverse: interfacing C / assembler from Ada. Some reasons, roughly: - there are interfacing facilities in Ada language for C/C++, Fortran,... - Ada has modularity, so an Ada package has a richer information than that you find in an .o file produced by assembler/C/C++ or any other macro-assembler; - there are initialisation sequences in an Ada package; - there are exceptions that should be able to be cascaded until the main procedure; - you can choose the main procedure without calling it "main" The thing you are trying to do is like interfacing C code into a main program in assembler... Hoping it helps... -- Gautier -------- http://members.xoom.com/gdemont/ ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Calling Ada proceedures from a C program 1999-05-20 0:00 Calling Ada proceedures from a C program Jason LaPenta 1999-05-20 0:00 ` Gautier @ 1999-05-20 0:00 ` David C. Hoos, Sr. 1999-05-20 0:00 ` Geert Bosch 1999-05-20 0:00 ` Compilier Im' using Jason LaPenta 1999-06-09 0:00 ` Calling Ada proceedures from a C program rekennedy 3 siblings, 1 reply; 11+ messages in thread From: David C. Hoos, Sr. @ 1999-05-20 0:00 UTC (permalink / raw) Jason LaPenta wrote in message <37444D8D.B6C7D7E5@orca.ds.boeing.com>... >Hello, > I have a linking/binding question. I'm trying to call an Ada proc. >from a C program. Something like... Before anyone can help, you need to specify at least the compiler you're using, as the procedure is compiler-dependent. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Calling Ada proceedures from a C program 1999-05-20 0:00 ` David C. Hoos, Sr. @ 1999-05-20 0:00 ` Geert Bosch 1999-05-21 0:00 ` Keith Thompson 0 siblings, 1 reply; 11+ messages in thread From: Geert Bosch @ 1999-05-20 0:00 UTC (permalink / raw) "David C. Hoos, Sr." wrote: > >I have a linking/binding question. I'm trying to call an Ada proc. > >from a C program. Something like... > Before anyone can help, you need to specify at least the compiler > you're using, as the procedure is compiler-dependent. This is not totally correct. The general mechanism, including initialization and finalization is standardized in Ada95. Look in the RM for pragma Export (C, ...), "adainit", "adafinal". Annex B is the place to look for most of the information. On the details for compilation commands you'd have to read your compiler's documentation. Regards, Geert ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Calling Ada proceedures from a C program 1999-05-20 0:00 ` Geert Bosch @ 1999-05-21 0:00 ` Keith Thompson 0 siblings, 0 replies; 11+ messages in thread From: Keith Thompson @ 1999-05-21 0:00 UTC (permalink / raw) Geert Bosch <geert@act-europe.fr> writes: > This is not totally correct. The general mechanism, including > initialization and finalization is standardized in Ada95. Look in > the RM for pragma Export (C, ...), "adainit", "adafinal". Annex B is > the place to look for most of the information. On the details for > compilation commands you'd have to read your compiler's documentation. "adainit" and "adafinal" are in B.1(39). I mention this because they were left out of the index. -- Keith Thompson (The_Other_Keith) kst@cts.com <http://www.ghoti.net/~kst> San Diego Supercomputer Center <http://www.sdsc.edu> <*> Techno-geek. Mouse bigger than phone. Bites heads off virtual chickens. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Compilier Im' using 1999-05-20 0:00 Calling Ada proceedures from a C program Jason LaPenta 1999-05-20 0:00 ` Gautier 1999-05-20 0:00 ` David C. Hoos, Sr. @ 1999-05-20 0:00 ` Jason LaPenta 1999-05-21 0:00 ` Robert Dewar 1999-06-09 0:00 ` Calling Ada proceedures from a C program rekennedy 3 siblings, 1 reply; 11+ messages in thread From: Jason LaPenta @ 1999-05-20 0:00 UTC (permalink / raw) The Compilier I'm Using is gcc and gnat gcc version 2.8.1 GNATMAKE 3.11b Thanks Jason Jason LaPenta wrote: > Hello, > I have a linking/binding question. I'm trying to call an Ada proc. > from a C program. Something like... > > extern void __test( void ); // Ada proc test in a file called test.adb > with ada defination in test.ads > > int main() > { > __test(); > > return 1; > } > > I'm compiling the test.ads and the main.C to object code and then trying > to link by using > gcc -o test.o main.o > The originol proc. is test (w/out the two underscores). I haven't been > able to find any examples of doing this sort of thing, so if you know of > any on the web or otherwise it would help to point me in the right > direction. > > thanks > jason > lapenta@orca.ds.boeing.com ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Compilier Im' using 1999-05-20 0:00 ` Compilier Im' using Jason LaPenta @ 1999-05-21 0:00 ` Robert Dewar 0 siblings, 0 replies; 11+ messages in thread From: Robert Dewar @ 1999-05-21 0:00 UTC (permalink / raw) In article <37446AC7.98F26D1A@orca.ds.boeing.com>, Jason LaPenta <lapenta@orca.ds.boeing.com> wrote: > The Compilier I'm Using is gcc and gnat > gcc version 2.8.1 > GNATMAKE 3.11b Be sure to consult the secret GNAT archives (otherwise known as the GNAT documentation) you will find useful stuff there, some of which is directly relevant to your question! Robert Dewar Ada Core Technologies P.S. I refer to them as the secret archives, because sometimes it seems that must be secret for so many people not to have read them :-) :-) --== Sent via Deja.com http://www.deja.com/ ==-- ---Share what you know. Learn what you don't.--- ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Calling Ada proceedures from a C program 1999-05-20 0:00 Calling Ada proceedures from a C program Jason LaPenta ` (2 preceding siblings ...) 1999-05-20 0:00 ` Compilier Im' using Jason LaPenta @ 1999-06-09 0:00 ` rekennedy 1999-06-09 0:00 ` Robert Dewar ` (2 more replies) 3 siblings, 3 replies; 11+ messages in thread From: rekennedy @ 1999-06-09 0:00 UTC (permalink / raw) In article <37444D8D.B6C7D7E5@orca.ds.boeing.com>, Jason LaPenta <lapenta@orca.ds.boeing.com> wrote: > Hello, > I have a linking/binding question. I'm trying to call an Ada proc. > from a C program. Something like... > > extern void __test( void ); // Ada proc test in a file called test.adb > with ada defination in test.ads > > int main() > { > __test(); > > return 1; > } > > I'm compiling the test.ads and the main.C to object code and then trying > to link by using > gcc -o test.o main.o > The originol proc. is test (w/out the two underscores). I haven't been > able to find any examples of doing this sort of thing, so if you know of > any on the web or otherwise it would help to point me in the right > direction. > > thanks > jason > lapenta@orca.ds.boeing.com > > I've recently been working on that same sort of thing, trying to provide C-bindings to some Ada code that we've developed. I'm using the gnat95 and gcc compilers on an WinNT system to do this. Most of the information you need for doing this is in Appendix B of the LRM that comes with gnat95, but some of it can be a bit difficult to find. Hardest part is that the examples in there and in every other source I've found only show the linkage in the other direction, Ada calling C procedures. To do the bindings, I ended up using pragma Export (C, my_procedure), then defining the procedure in a header file. I've been working on a small set of test files first, trying to figure out the details of the linking, data passing, etc. I've got a small ada package, named my_test_package, that is called from a c main in a file named my_test. Here's a copy of the steps I use to link these: gcc -c my_test_package.ads gcc -c my_test_package.adb gnatbind -n my_test_package.ali gcc my_test.c b_my_test_package.c my_test_package.o -L. -Lc: \gnat\bindings\win32ada\ -Lc:\gnat\lib\gcc-lib\pentium-mingw32msv\2.8.1 \adalib -lgnat Hope that helps with your problem. One of the things that I ran into early was getting the data types to match up. Finding the Interfaces.C and Interfaces.C.Strings packages provided by gnat made this task much easier. In the test packages, I've been trying to work with a couple of procedures and a couple of functions. The functions accept either an integer or a string, echo the value out to the screen, and then return the input value. Got both of those working, once I started using the interfaces types. The procedures do the same thing the functions do, except the value is returned in an out parameter. I've got it working for the integer. It was a bit tricky to get working, until I re-read appendix B where it talks about how out and in/out parms are handled. On the C-side, the input has to be an int, but the output has to be a pointer to int. On the Ada side, both values are declared as int. The compiler treats the output as a pointer under the covers. I'm having trouble getting the same thing to work for strings. For the strings, I ended up using the "char_ptr" type from Interfaces.C.Strings. On the c-side, the values are char *, on the Ada-side, they are char_ptr. The C calls the Ada procedure without a problem, until the code starts to return to the C, passing the value back. At that point, it raises an access violation. Still not sure what I'll have to do to get this working. If anyone has done this, I'd really appreciate any advice on it. I'll list the specs, headers, etc of the files here as an example of one way of doing this. Hopefully it will keep someone else from having the same frustrations looking for examples. Robert Kennedy Science Applications International Corporation (SAIC) my_test.c #include "my_test_package.h" int main() { int Int_Parm_One; int * Int_Parm_Two; int Int_Parm_Three; int foo; char * String_Parm_One; char * String_Parm_Two; foo = 10; Int_Parm_One = 5; Int_Parm_Two = &foo; String_Parm_One = "InputVal\0"; String_Parm_Two = "OutputVal\0"; adainit(); my_procedure_one(Int_Parm_One, Int_Parm_Two); printf ("Back from my_procedure_one, output = %d \n", *Int_Parm_Two); my_procedure_two(String_Parm_One, String_Parm_Two); printf ("Back from my_procedure_two, output = %s \n", String_Parm_Two); Int_Parm_Three = my_function_one(Int_Parm_One); printf ("Back from my_function_one, output = %d \n", Int_Parm_Three); String_Parm_Two = my_function_two(String_Parm_One); printf ("Back from my_function_one, output = %s \n", String_Parm_Two); adafinal(); return 0; } my_test_package.h #ifndef __MY_TEST_PACKAGE #define __MY_TEST_PACKAGE extern void my_procedure_one(int Parm_One, int * Parm_Two); extern void my_procedure_two(char * Parm_One, char * Parm_Two); extern int my_function_one(int Parm_One); extern char * my_function_two(char * Parm_Two); extern void adainit(); extern void adafinal(); #endif my_test_package.ads with Interfaces.C; with Interfaces.C.Strings; package My_Test_Package is package Ic renames Interfaces.C; package Ics renames Interfaces.C.Strings; type int_ptr is access ic.int; -- procedure My_Procedure_One; procedure My_Procedure_One ( Parm_One : in Ic.Int; Parm_Two : out ic.int); pragma Export(C, My_Procedure_One); -- procedure My_Procedure_Two procedure My_Procedure_Two( Parm_One : in Ics.Chars_Ptr; Parm_Two : out Ics.Chars_Ptr); pragma Export(C, My_Procedure_Two); -- function My_Function_One; function My_Function_One (Parm_One : Ic.Int) return Ic.int; pragma Export(C, My_Function_One); -- function My_Function_One; function My_Function_Two (Parm_One : Ics.Chars_Ptr) return Ics.Chars_Ptr; pragma Export(C, My_Function_Two); end My_Test_Package; Sent via Deja.com http://www.deja.com/ Share what you know. Learn what you don't. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Calling Ada proceedures from a C program 1999-06-09 0:00 ` Calling Ada proceedures from a C program rekennedy @ 1999-06-09 0:00 ` Robert Dewar 1999-06-10 0:00 ` David Kristola 1999-06-11 0:00 ` David C. Hoos, Sr. 2 siblings, 0 replies; 11+ messages in thread From: Robert Dewar @ 1999-06-09 0:00 UTC (permalink / raw) In article <7jlsqd$khj$1@nnrp1.deja.com>, rekennedy@my-deja.com wrote: > One of the things that I ran into early was getting the data > types to match up. Finding the Interfaces.C and > Interfaces.C.Strings packages > provided by gnat made this task much easier. Well I should hope these are provided by GNAT, since they are a required part of the Ada 95 language if you provide interfacing to C. One thing I often notice is that people struggle to do things which are actually quite simple, from not having done enough homework to know all the facilities that are available. The issue of how to interface from Ada to C is covered in a number of Ada text books, and if the description in the RM is not clear, then you should definitely find one of these texts. My recommendation is to at least read annexes A and B in the RM, these are quite readable, and describe a lot of useful stuff (including the children of Ada mentioned in the quote above). Sent via Deja.com http://www.deja.com/ Share what you know. Learn what you don't. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Calling Ada proceedures from a C program 1999-06-09 0:00 ` Calling Ada proceedures from a C program rekennedy 1999-06-09 0:00 ` Robert Dewar @ 1999-06-10 0:00 ` David Kristola 1999-06-11 0:00 ` David C. Hoos, Sr. 2 siblings, 0 replies; 11+ messages in thread From: David Kristola @ 1999-06-10 0:00 UTC (permalink / raw) In article 1@nnrp1.deja.com, rekennedy@my-deja.com () writes: >I'm having trouble getting the same thing to work for strings. For the >strings, I ended up using the "char_ptr" type from Interfaces.C.Strings. >On the c-side, the values are char *, on the Ada-side, they are >char_ptr. The C calls the Ada procedure without a problem, until the >code starts to return to the C, passing the value back. At that point, >it raises an access violation. Still not sure what I'll have to do to >get this working. If anyone has done this, I'd really appreciate any >advice on it. > >I'll list the specs, headers, etc of the files here as an example of >one way of doing this. Hopefully it will keep someone else from having >the same frustrations looking for examples. > > >Robert Kennedy >Science Applications International Corporation (SAIC) You did not include the body for My_Test_Package, so i am not sure what it is doing, but the problem may be in the way out parameters are handled. As with the integer case, Ada may use a pointer to the string pointer. I am sure this is in the documentation somewhere, but i do not have it close at hand. --djk, keeper of arcane lore & trivial fluff Home: David95037 at aol dot com Spam: goto.hades@welovespam.com ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Calling Ada proceedures from a C program 1999-06-09 0:00 ` Calling Ada proceedures from a C program rekennedy 1999-06-09 0:00 ` Robert Dewar 1999-06-10 0:00 ` David Kristola @ 1999-06-11 0:00 ` David C. Hoos, Sr. 2 siblings, 0 replies; 11+ messages in thread From: David C. Hoos, Sr. @ 1999-06-11 0:00 UTC (permalink / raw) [-- Warning: decoded text below may be mangled, UTF-8 assumed --] [-- Attachment #1: Type: text/plain, Size: 4480 bytes --] rekennedy@my-deja.com wrote in message <7jlsqd$khj$1@nnrp1.deja.com>... <large snip> Your problem with my_procedure_two is that its prototype should be extern void my_procedure_two(char * Parm_One, char * * Parm_Two); instead of extern void my_procedure_two(char * Parm_One, char * Parm_Two); In other words, you need the added level of indirection on the out mode parameter, just as you did for the second parameter of my_procedure_one. Of course, the call to my_procedure_two would be my_procedure_two(String_Parm_One, & String_Parm_Two); instead of my_procedure_two(String_Parm_One, String_Parm_Two); However, note that what you're doing here is allocating memory in my_procedure_two, where the only pointer to that memory is String_Parm_Two. So, the following from the Ada RM B.3.1 (58-60) is pertinent. NOTES 58 13 New_Char_Array and New_String might be implemented either through the allocation function from the C environment (�malloc�) or through Ada dynamic memory allocation (�new�). The key points are 59 � the returned value (a chars_ptr) is represented as a C �char *� so that it may be passed to C functions; 60 � the allocated object should be freed by the programmer via a call of Free, not by a called C function. (I have no idea what is the significance of the "13" in (58) above.) This means, that if you wanted to be able to free the memory so allocated, you need to do it like this: Ada spec: procedure Free (The_Memory : in out Interfaces.C.Strings.Chars_Ptr); pragma Export (C, Free, "Free"); Ada body: procedure Free (The_memory : in out Interfaces.C.Strings.Chars_Ptr) is begin Interfaces.C.Strings.Free (The_Memory); end Free; C prototype: void Free (char ** the_memory); Just a couple of small hints about your C code: 1. The \0 at the end of the string literals in the next two statements are superfluous, because string literals in C are automatically NUL-terminated by the compiler. String_Parm_One = "InputVal\0"; String_Parm_Two = "OutputVal\0"; 2. When you call my_procedure_two, the value of String_Parm_Two will be overwritten, thereby "orphaning" the memory where the string literal resides. >my_test.c > >#include "my_test_package.h" > >int main() >{ > int Int_Parm_One; > int * Int_Parm_Two; > int Int_Parm_Three; > int foo; > char * String_Parm_One; > char * String_Parm_Two; > > foo = 10; > Int_Parm_One = 5; > Int_Parm_Two = &foo; > String_Parm_One = "InputVal\0"; > String_Parm_Two = "OutputVal\0"; > > adainit(); > my_procedure_one(Int_Parm_One, Int_Parm_Two); > printf ("Back from my_procedure_one, output = %d \n", *Int_Parm_Two); > > my_procedure_two(String_Parm_One, String_Parm_Two); > printf ("Back from my_procedure_two, output = %s \n", >String_Parm_Two); > > Int_Parm_Three = my_function_one(Int_Parm_One); > printf ("Back from my_function_one, output = %d \n", Int_Parm_Three); > > String_Parm_Two = my_function_two(String_Parm_One); > printf ("Back from my_function_one, output = %s \n", String_Parm_Two); > > adafinal(); > return 0; >} > > >my_test_package.h > >#ifndef __MY_TEST_PACKAGE >#define __MY_TEST_PACKAGE > >extern void my_procedure_one(int Parm_One, int * Parm_Two); >extern void my_procedure_two(char * Parm_One, char * Parm_Two); >extern int my_function_one(int Parm_One); >extern char * my_function_two(char * Parm_Two); > >extern void adainit(); >extern void adafinal(); > >#endif > > >my_test_package.ads > >with Interfaces.C; >with Interfaces.C.Strings; > >package My_Test_Package is > > package Ic renames Interfaces.C; >package Ics renames Interfaces.C.Strings; > type int_ptr is access ic.int; > >-- procedure My_Procedure_One; >procedure My_Procedure_One ( > Parm_One : in Ic.Int; > Parm_Two : out ic.int); >pragma Export(C, My_Procedure_One); > >-- procedure My_Procedure_Two >procedure My_Procedure_Two( > Parm_One : in Ics.Chars_Ptr; > Parm_Two : out Ics.Chars_Ptr); >pragma Export(C, My_Procedure_Two); > >-- function My_Function_One; >function My_Function_One (Parm_One : Ic.Int) return Ic.int; >pragma Export(C, My_Function_One); > >-- function My_Function_One; >function My_Function_Two (Parm_One : Ics.Chars_Ptr) > return Ics.Chars_Ptr; >pragma Export(C, My_Function_Two); > >end My_Test_Package; > > >Sent via Deja.com http://www.deja.com/ >Share what you know. Learn what you don't. ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~1999-06-11 0:00 UTC | newest] Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 1999-05-20 0:00 Calling Ada proceedures from a C program Jason LaPenta 1999-05-20 0:00 ` Gautier 1999-05-20 0:00 ` David C. Hoos, Sr. 1999-05-20 0:00 ` Geert Bosch 1999-05-21 0:00 ` Keith Thompson 1999-05-20 0:00 ` Compilier Im' using Jason LaPenta 1999-05-21 0:00 ` Robert Dewar 1999-06-09 0:00 ` Calling Ada proceedures from a C program rekennedy 1999-06-09 0:00 ` Robert Dewar 1999-06-10 0:00 ` David Kristola 1999-06-11 0:00 ` David C. Hoos, Sr.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox