c - 从 C 调用 Ada 时 Ada 查找表不起作用

标签 c gcc makefile ada gnat

我正在处理一些我必须从 C 调用的 Ada 代码,我遇到了一个我无法解决的问题,也不知道为什么会这样。

下面是一个测试项目来说明问题:

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;

查找.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;

主.adb

with lookup;

procedure main is
begin
    lookup.PrintLookup;
end 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 将生成一个名为ma​​in 的可执行文件。如果 makefile 第一行的 BUILD 变量设置为 ada,它将使用 Ada main.adb,否则 C < em>main.c

现在,问题来了:如果在 lookup.adb 中我使用 Month_Length 数组的第一个变体(现在已被注释掉),我得到两个主电源的以下输出是正确的:

Month_Length(5): 31

但是对于另一个数组(称为查找表),C 变体返回 0:

Month_Length(5): 0

有谁知道为什么从 C 调用查找表数组时返回 0? 有人遇到过这个问题吗? 我错过了什么? 感谢您的帮助。

最佳答案

作为Vroomfondel评论中提到,必须调用 adainit 来初始化 ADA。 以下是我为使其正常工作所做的修改:

这是生成文件:

BUILD=c

GM=gnatmake
GB=gnatbind
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 b~lookup.o main.o -o $@ -lgnat

lookup.o:
    $(GM) lookup.adb
    $(GB) -n lookup.ali
    $(GM) b~lookup.adb

main.o:
    $(CC) -c main.c
endif


.PHONY: clean
clean:
    rm -f lookup.ali lookup.o
    rm -f b~lookup.*
    rm -f main.ali main.o
    rm -f main

gnatbind 生成 b~lookup.adsb~lookup.adb 文件,其中将包含 adainit()adafinal() 函数,然后我用 gnatmake 构建了它们(我不得不构建因为我没有使用 gnatlink ) 并且我在链接部分包含了生成的 b~lookup.o 文件。

main.c 必须修改如下(只需在 ADA 调用前后调用 init 和 final 函数):

extern void print_lookup();
extern void adainit();
extern void adafinal();

int main()
{
    adainit();
    print_lookup();
    adafinal();

    return 0;
}

其余保持不变。

关于c - 从 C 调用 Ada 时 Ada 查找表不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53445732/

相关文章:

c - 将参数传递到 ./configure

c++ - 计算位和位反相中有多少个

c++ - 解析网络头时字段的字节顺序

c - C代码中的SSE2指令

gcc - OpenMP 是否支持工作窃取机制?

c++ - "throw"程序崩溃,但编译正常

bash - Makefile 错误 - 寻找匹配 `"时意外的 EOF '

C - 字符 *' differs in levels of indirection from ' 字符 (*)[200]

c - 3D ASCII 正弦波发生器产生奇怪的正弦波

c++ - C++ 的简单生成文件