I'm working on some Ada code which I have to call from C and I've encountered a problem which I can't solve and don't know why it's happening.
Here is a test project to illustrate the problem:
lookup.ads
with Interfaces.C; use Interfaces.C; package lookup is procedure Printf(str : in Interfaces.C.char_array; i : in Positive); pragma Import(C, printf, "printf"); procedure PrintLookup; pragma Export(C, PrintLookup, "print_lookup"); end lookup; lookup.adb
with Interfaces.C; use Interfaces.C; package body lookup is -- Month_Length : constant array (1..12) of Positive := (31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); Month_Length : constant array (1..12) of Positive := (4 | 6 | 9 | 11 => 30, 2 => 28, others => 31); procedure PrintLookup is begin printf("Month_Length(5): %d"&To_C(ascii.LF)&To_C(ascii.NUL), Month_Length(5)); end PrintLookup; end lookup; main.adb
with lookup; procedure main is begin lookup.PrintLookup; end main; main.c
extern void print_lookup(); int main() { print_lookup(); return 0; } And I have a simple makefile to build it:
BUILD=ada GM=gnatmake CC=gcc LIB=-L/usr/lib/gcc/i686-linux-gnu/4.9/adalib ifeq ($(BUILD),ada) main: $(GM) lookup.adb main.adb else main: lookup.o main.o $(CC) $(LIB) lookup.o main.o -o $@ -lgnat lookup.o: $(GM) lookup.adb main.o: $(CC) -c main.c endif .PHONY: clean clean: rm -f lookup.ali lookup.o rm -f main.ali main.o rm -f main The makefile will generate an executable, called main. If the BUILD variable in the first line of the makefile is set to ada, it will use the Ada main.adb, otherwise the C main.c
Now, here comes the problem: if in the lookup.adb I use the first variant of the Month_Length array (which is commented out right now), I get the following output for both mains, which is correct:
Month_Length(5): 31
But in case of the other array (which is called a lookup table), the C variant returns 0:
Month_Length(5): 0
Does anyone have any idea why the lookup table array returns 0 when called from C? Does anyone encountered this issue? What am I missing? I appreciate your help.
adainitYou must call this routine to initialize the Ada part of the program by calling the necessary elaboration routines. A call to adainit is required before the first call to an Ada subprogram."