Windows pragma导出函数在Ada可执行文件中不是外部函数 我需要一个VisualStudioC++ + DLL,能够在我的艾达主线中调用一个函数。Ada代码有一个函数规范,如 package offset is function GET_OFFSET return integer; pragma Export (Stdcall, GET_OFFSET, "fnAdaOffset"); end offset; C++函数将调用艾达方法如下:< /P> typedef int (*tdAdaOffset)(void); tdAdaOffset _ptAdaOffset = NULL; int AdaOffset() { if (_ptAdaOffset == NULL) { _ptAdaOffset = (tdAdaOffset)GetProcAddress(GetModuleHandle(NULL), "fnAdaOffset@0"); if (_ptAdaOffset == NULL) throw "Function not found"; } return (*_ptAdaOffset)(); }

Windows pragma导出函数在Ada可执行文件中不是外部函数 我需要一个VisualStudioC++ + DLL,能够在我的艾达主线中调用一个函数。Ada代码有一个函数规范,如 package offset is function GET_OFFSET return integer; pragma Export (Stdcall, GET_OFFSET, "fnAdaOffset"); end offset; C++函数将调用艾达方法如下:< /P> typedef int (*tdAdaOffset)(void); tdAdaOffset _ptAdaOffset = NULL; int AdaOffset() { if (_ptAdaOffset == NULL) { _ptAdaOffset = (tdAdaOffset)GetProcAddress(GetModuleHandle(NULL), "fnAdaOffset@0"); if (_ptAdaOffset == NULL) throw "Function not found"; } return (*_ptAdaOffset)(); },windows,dll,ada,gnat,gnat-gps,Windows,Dll,Ada,Gnat,Gnat Gps,我相信这会奏效。我遇到的问题是Ada拒绝在可执行文件中将函数GET_OFFSET标记为外部,即执行dumpbin/exports Ada.exe不会显示任何导出函数 我读过各种解决方案,如,但我的链接器似乎太老了,不知道这个开关 另一个很有希望的选择是在链接步骤中添加-shared,但是虽然这现在公开了函数,但它也将输出文件更改为DLL(扩展名为.EXE(!),因此也没有什么用处 在升级我的工具链之前,我是否可以尝试其他链接器开关或其他建议?您需要告诉链接器从可执行文件导出符号ld有一个选项--

我相信这会奏效。我遇到的问题是Ada拒绝在可执行文件中将函数GET_OFFSET标记为外部,即执行dumpbin/exports Ada.exe不会显示任何导出函数

我读过各种解决方案,如,但我的链接器似乎太老了,不知道这个开关

另一个很有希望的选择是在链接步骤中添加-shared,但是虽然这现在公开了函数,但它也将输出文件更改为DLL(扩展名为.EXE(!),因此也没有什么用处


在升级我的工具链之前,我是否可以尝试其他链接器开关或其他建议?

您需要告诉链接器从可执行文件导出符号
ld
有一个选项--export dynamic,但是:

请注意,此选项特定于ELF目标端口。PE目标支持从DLL或EXE导出所有符号的类似功能;请参见下面的描述--导出所有符号

因此,在Windows上,您需要使用
——导出所有符号

根据编译Ada代码的方式,可能需要通过编译器命令(
gcc
)传递此选项。要告诉
gcc
链接器将使用某个选项,请在其前面加上
-Wl
,然后给链接器选项加逗号。在这种情况下,您将得到
-Wl,--export-all-symbol

如果您使用的是GPRBuild,
.gpr
文件的相关部分如下所示:

程序包链接器不可用
对于默认的_开关(“Ada”)使用(“-Wl,--导出所有符号”);
末端连接器;

旁注:

  • 请注意,C++的
    int
    不一定与Ada的
    Integer
    相同,您应该使用
    Interfaces.C.int
    作为Ada中的返回类型
  • 调用约定必须匹配<艾达中的代码> STDCALL//COD>在C++中匹配显式<代码>如果在C++代码中没有<代码>艾达的代码,请在代码中使用<代码> C < /COD>调用约定。
我相信您需要
-Wl,--export dynamic
从可执行文件导出函数,但是,我从来没有这样做过。如果你不在C++中指定<代码>艾达>代码,那么你不应该在代码中使用<代码> STDCALL> /CODE >。我有一个问题可能会影响这个问题的答案:初始化/终结如何在这方面起作用。通常,在C++中使用艾达DLL时,必须先绑定并使用初始化例程,然后调用艾达例程,然后在调用后调用绑定终结例程。我觉得这可能在这里适用,但不确定具体是什么原因,因为作者没有指定这是艾达调用C++ DLL调用艾达例程VC++调用C++ DLL调用艾达。routine@flyx,您就快到了:创建EXE时正确的开关是
-Wl,-export all symbols
。我必须升级到GNATGPL的更新版本才能使用它。提交答案,我会把它标记为正确的。@杰尔,因为我的主线是写在艾达,所有的阐述将在我调用Visual C++例程的时候,这又将调用艾达。谢谢你的提醒。