如何链接Ada中的自定义dll?

问题描述:

因此,这是一个简单的项目,我之前将它们放在一起进行测试,然后再做一些很酷的事情。最终的目标是让程序能够通过真棒dll功夫来处理模块化。如何链接Ada中的自定义dll?

但是,宝贝的步骤。现在我只想制作链接。

这里我有Adder.ads:

package Adder is 

    function Add(A : Integer; B : Integer) return Integer; 

end Adder; 

和各自Adder.adb:

package body Adder is 

    function Add(A : Integer; B : Integer) return Integer is 
    begin 
     return A + B; 
    end Add; 

end Adder; 

令人兴奋的,我知道。

我已经看到了如何做到这一点,他们都不同意,但是从this one采取了线索几个不同的教程,我想出了这些命令:

gnatmake -c Adder.adb 
gcc -shared -shared-libgcc -o Adder.dll Adder.o 

这至少产生 dll。我不知道它是否会生成一个实际上可以工作的问题,或者如果问题出在主要的exe文件上。

现在主要的exe文件,我把所有东西放在一个单独的目录下,所以gnat不会试图欺骗和使用.ali和.o文件。然后,在尝试构建之前将dll复制到目录中。我已经尝试了很多不同的方法,并得到了几个不同的错误,但这是我现在所拥有的。

Main.adb:

with Adder_Spec; use Adder_Spec; 
with Ada.Text_IO; use Ada.Text_IO; 

procedure Main is 
begin 
    Put_Line(Integer'Image(Add(3,4))); 
end Main; 

耶最无用的程序永远。现在,知道我应该对DLL中的规范,我想出了aforewith'd Adder_Spec.ads:

package Adder_Spec is 

    function Add(A : Integer; B : Integer) return Integer; 

private 

    pragma Import(Ada, Add, "Add"); 

end Adder_Spec; 

现在,就像我说我已经试过这一堆不同的方式,有时省略第三个导入参数,其他时间完全省略导入,有时保留导入但不将其分隔到私有部分,您可以将其命名。我也试着用编译命令打几个方面,但这里是最近的一个:

gnatmake Main.adb -bargs -shared -largs -lAdder 

有了它吐出了一个“未定义的引用“添加”错误这个特殊的命令。如果我添加-v标志,它不会提供更多有用的信息。

检查gnatmake --help显示默认模式是gnat 2012,如果这有什么区别。这可能不应该,因为我已经试着编译2005年和95年的国旗。

因此......任何人都可以发现问题吗?提前致谢。

+0

从技术上讲,这是一个GNAT问题,而不是一个Ada问题(但我认为保持“ada”标记无论如何都是最合理的)。 –

+1

当你说'gcc -shared -shared-libgcc -o Adder.dll -Adder.o'时,我想你一定是指'Adder.o'? –

+0

@SimonWright是的,很好。 – Devsman

如果你想说

package Adder_Spec is 
    function Add(A : Integer; B : Integer) return Integer; 
private 
    pragma Import(Ada, Add, "Add"); 
end Adder_Spec; 

导入DLL的时候,那么你不得不说

package Adder is 
    function Add(A : Integer; B : Integer) return Integer; 
    pragma Export (Ada, Add, "Add"); 
end Adder; 

建设时。

GNAT生成的Add的默认链接器名称是(我认为)adder__add;你应该能够看到它使用的是什么nm Adder.o

+0

AFAIK一个编译指示出口应该在导入的合同定义之后声明:没有任何关于其范围的歧义。随着私人部分申报的出口和公共部分的合同,无论如何预期的行为是什么?为什么需要这样的建筑? – LoneWanderer

+0

@LoneWanderer - 如果你检查[ARM05 B.1(51)](http://www.adaic.org/resources/add_content/standards/05rm/html/RM-B-1.html#p51),你会看到在私人部分申报出口。我会想象如果在查看编译指示之前使用子程序,可能会出现问题,可能是通过声明一个初始化为函数调用结果的变量;这里和上面的例子中的想法必须是从那些真正不需要知道的人的眼睛中隐藏混乱的细节。现在,当然,'Convention','Export'和'External_Name'方面就在你的面前! –

+0

你达人,西蒙。我应该猜到了。 – Devsman

我建议您按照AdaCore的“Ada插件和共享库”(part 1,part 2)中的说明进行操作。

我已经使用了那里描述的技术,它工作得很好。

+0

我一定会看看这个;谢谢! – Devsman