我正在处理一些Ada代码,需要从C中调用它,但我遇到了一个问题,无法解决,也不知道为什么会出现这个问题。
这里是一个测试项目,以说明这个问题: lookup.ads
我有一个简单的 Makefile 来构建它:
该makefile将生成一个名为main的可执行文件。如果makefile的第一行中的BUILD变量设置为ada,它将使用Ada的main.adb,否则使用C的main.c。
现在,问题来了:如果在lookup.adb中使用Month_Length数组的第一个变体(当前已注释掉),则两个主程序的输出如下,这是正确的:
这里是一个测试项目,以说明这个问题: 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;
}
我有一个简单的 Makefile 来构建它:
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
该makefile将生成一个名为main的可执行文件。如果makefile的第一行中的BUILD变量设置为ada,它将使用Ada的main.adb,否则使用C的main.c。
现在,问题来了:如果在lookup.adb中使用Month_Length数组的第一个变体(当前已注释掉),则两个主程序的输出如下,这是正确的:
但是在另一个数组(称为查找表)的情况下,C变量返回0:Month_Length(5): 31
有人知道为什么从C调用查找表数组时会返回0吗? 有人遇到过这个问题吗? 我需要注意什么吗? 感谢您的帮助。Month_Length(5): 0
adainit
在第一次调用Ada子程序之前,您必须调用此例程以调用必要的实体化例程,从而初始化程序的Ada部分。必须在第一次调用Ada子程序之前调用adainit。"
- Vroomfondel