* Need Help Calling Ada From C
@ 1998-12-05 0:00 David Hoffman
1998-12-09 0:00 ` Mats Weber
1998-12-12 0:00 ` Simon Wright
0 siblings, 2 replies; 3+ messages in thread
From: David Hoffman @ 1998-12-05 0:00 UTC (permalink / raw)
Hi,
I am trying to figure out how to call an Ada function from a C program.
For the record I am using GNAT 3.10p on Linux (Slackware, kernel 2.0.33).
I read what I could find on the net, in the GNAT manual, and in several
Ada books that I have. Since I did not find a complete, step-by-step ex-
ample I had to make a few guesses (and maybe that is where things went
wrong).
I created a C program, called fact.c, that calls an Ada function from a
package called first_test (the source code for these items is given at
the end of this message). I compiled this with the commands:
$ gcc -c first_test.ads
$ gcc -c first_test.adb
$ gnatbind -n first_test.ali
$ gcc -c b_first_test.c
$ gcc -c fact.c
I made it this far without any real trouble. Then I got this:
$ gcc -o fact *.o
b_first_test.o: In function `adainit':
b_first_test.o(.text+0x26): undefined reference to `__gnat_set_globals'
b_first_test.o(.text+0x2e): undefined reference to `system__elabs'
b_first_test.o(.text+0x33): undefined reference to
`system__exception_table___elabb'
b_first_test.o(.text+0x38): undefined reference to `interfaces__c___elabs'
b_first_test.o(.text+0x3d): undefined reference to
`system__tasking_soft_links___elabb'
b_first_test.o(.text+0x42): undefined reference to
`system__secondary_stack___elabb'
fact.o: In function `main'
fact.o(.text+0x30): undefined reference to `fact'
Where did I go wrong?
David Hoffman
david.a.hoffman1@jsc.nasa.gov
fact.c --------------------------------------------------------------------
extern void adainit();
extern void adafinal();
extern long factorial( long N );
main (argc, argv)
char *argv[];
int argc;
{
long answer, value;
adainit();
value = atol(argv[1]);
if ( value 0 )
{
if ( value <= 12 )
{
answer = factorial(value);
printf("\n %2d! = %3d\n",value,answer);
}
else
{
printf("\n fact: input value too big (would cause
overflow).\n");
}
}
else
{
printf("\n fact: input must be strictly positive.\n");
}
adafinal();
}
first_test.ads ---------------------------------------------------------
with Interfaces.C; use Interfaces;
package First_Test is
function Factorial ( Value : C.long ) return C.long;
pragma Export (C, Factorial, "factorial");
end First_Test;
first_test.adb ---------------------------------------------------------
with Interfaces.C; use Interfaces;
first_test.adb
package body First_Test is
function Ada_Factorial (N : Integer) return Integer is
begin
if N = 1 then
return 1;
else
return N * Ada_Factorial(N-1);
end if;
end;
function Factorial (Value : C.long) return C.long is
P,Q : Integer;
begin
P := Integer(Value);
Q := Ada_Factorial(P);
return C.long(Q);
end;
end First_Test;
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Need Help Calling Ada From C
1998-12-05 0:00 Need Help Calling Ada From C David Hoffman
@ 1998-12-09 0:00 ` Mats Weber
1998-12-12 0:00 ` Simon Wright
1 sibling, 0 replies; 3+ messages in thread
From: Mats Weber @ 1998-12-09 0:00 UTC (permalink / raw)
David Hoffman wrote:
> $ gcc -c first_test.ads
> $ gcc -c first_test.adb
> $ gnatbind -n first_test.ali
> $ gcc -c b_first_test.c
> $ gcc -c fact.c
>
> I made it this far without any real trouble. Then I got this:
>
> $ gcc -o fact *.o
You need to give gcc the library locations:
gcc fact.o first_test.o b_first_test.c -L/usr/local/.../adalib/ -lgnat
^^^ exact location is
system dependant.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Need Help Calling Ada From C
1998-12-05 0:00 Need Help Calling Ada From C David Hoffman
1998-12-09 0:00 ` Mats Weber
@ 1998-12-12 0:00 ` Simon Wright
1 sibling, 0 replies; 3+ messages in thread
From: Simon Wright @ 1998-12-12 0:00 UTC (permalink / raw)
hoffman@insync.net (David Hoffman) writes:
> I am trying to figure out how to call an Ada function from a C program.
> For the record I am using GNAT 3.10p on Linux (Slackware, kernel 2.0.33).
> I read what I could find on the net, in the GNAT manual, and in several
> Ada books that I have. Since I did not find a complete, step-by-step ex-
> ample I had to make a few guesses (and maybe that is where things went
> wrong).
>
> I created a C program, called fact.c, that calls an Ada function from a
> package called first_test (the source code for these items is given at
> the end of this message). I compiled this with the commands:
>
> $ gcc -c first_test.ads
> $ gcc -c first_test.adb
> $ gnatbind -n first_test.ali
> $ gcc -c b_first_test.c
> $ gcc -c fact.c
>
> I made it this far without any real trouble. Then I got this:
>
> $ gcc -o fact *.o
> b_first_test.o: In function `adainit':
> b_first_test.o(.text+0x26): undefined reference to `__gnat_set_globals'
> b_first_test.o(.text+0x2e): undefined reference to `system__elabs'
> b_first_test.o(.text+0x33): undefined reference to
> `system__exception_table___elabb'
> b_first_test.o(.text+0x38): undefined reference to `interfaces__c___elabs'
> b_first_test.o(.text+0x3d): undefined reference to
> `system__tasking_soft_links___elabb'
> b_first_test.o(.text+0x42): undefined reference to
> `system__secondary_stack___elabb'
> fact.o: In function `main'
> fact.o(.text+0x30): undefined reference to `fact'
If you look at the C file generated by gnatbind (b_first_test.c) you
will find at the end a section like the example below, which tells
what the linker needs to see:
/* BEGIN Object file/option list
./buggy.o
-L./
-L/u1/simon/gnat/lib/gcc-lib/i386-linux/2.7.2.1/adalib/
-L/usr/lib/gcc-lib/i386-linux/2.7.2.1/adalib/
-lgnat
END Object file/option list */
You need to give the bit between the BEGIN and END lines to the
linker. I've used GNU Make rules as below to create a 'response' file:
b_%.c: %.ali
gnatbind -n $(DEB) $(ADAINCLUDES) $<
b_%.o: b_%.c
gcc -c $<
%.rsp: %.c
sed -n -e "/BEGIN/,/END/p" < $*.c | egrep -v "BEGIN|END" > $*.rsp
and then (foo.o comes from foo.c, foo_body is written in Ada):
foo: b_foo_body.rsp b_foo_body.o foo.o
gcc $(LDFLAGS) -o foo foo.o b_foo_body.o \
`cat b_foo_body.rsp` \
(... other stuff)
I'm perfectly sure there's a better way of generating that response file!
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~1998-12-12 0:00 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-12-05 0:00 Need Help Calling Ada From C David Hoffman
1998-12-09 0:00 ` Mats Weber
1998-12-12 0:00 ` Simon Wright
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox