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.5 required=5.0 tests=BAYES_00,INVALID_MSGID, PP_MIME_FAKE_ASCII_TEXT autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII X-Google-Thread: 103376,4e101bd1b1b0a66c X-Google-Attributes: gid103376,public From: "David C. Hoos, Sr." Subject: Re: Calling Ada proceedures from a C program Date: 1999/06/11 Message-ID: <7jrojm$c26@hobbes.crc.com>#1/1 X-Deja-AN: 488536274 References: <37444D8D.B6C7D7E5@orca.ds.boeing.com> <7jlsqd$khj$1@nnrp1.deja.com> Organization: Coleman Research Corporation X-MimeOLE: Produced By Microsoft MimeOLE V4.72.3612.1700 Newsgroups: comp.lang.ada Date: 1999-06-11T00:00:00+00:00 List-Id: rekennedy@my-deja.com wrote in message <7jlsqd$khj$1@nnrp1.deja.com>... 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.