windows - pragma 导出函数在 Ada 可执行文件中不是外部的

标签 windows dll ada gnat gnat-gps

我需要一个 Visual Studio C++ DLL 能够调用我的 Ada 主线中的函数。 Ada 代码的函数规范如下:

package offset is
    function GET_OFFSET return integer;
    pragma Export (Stdcall, GET_OFFSET, "fnAdaOffset");
end offset;

然后,C++ 函数将调用 Ada 方法,如下所示:

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)();
}

我相信这会起作用。我遇到的问题是 Ada 拒绝将函数 GET_OFFSET 标记为可执行文件中的外部函数,即执行 dumpbin/exports ada.exe 显示没有导出的函数。

我读过各种解决方案,例如 --version-script for the linker ,但我的链接器似乎太旧了,无法了解此开关。

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

在升级工具链之前,我可以尝试另一个链接器开关,或者有其他建议吗?

最佳答案

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

Note that this option is specific to ELF targeted ports. PE targets support a similar function to export all symbols from a DLL or EXE ; see the description of --export-all-symbols below.

因此,在 Windows 上,您需要使用 --export-all-symbols

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

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

package Linker is
  for Default_Switches ("Ada") use ("-Wl,--export-all-symbols");
end Linker;

旁注:

  • 请注意,C++ 的 int 不一定与 Ada 的 Integer 相同,您应该使用 Interfaces.C.int 作为返回类型改为艾达。
  • 调用约定必须匹配。 Ada 中的 Stdcall 与 C++ 中的显式 __stdcall 相匹配。如果 C++ 代码中没有 __stdcall,请改用 Ada 中的 C 调用约定。

关于windows - pragma 导出函数在 Ada 可执行文件中不是外部的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63945894/

相关文章:

windows - COM dll 不再注册

windows - Postgres 安装失败

java - 如何通过java程序获取exe运行的进程id

windows - 如何从显示设备名称中获取 HMONITOR 句柄?

visual-c++ - _imp 和 __imp 有什么区别?

dll - 具有 native 依赖和复制文件的 Maven 项目

oop - Ada - 如何初始化包含 File_Type 成员的有限标记类型?

embedded - Ada 中的信号量

windows - 使用 Msys2 为 mingw 安装 Rust 和 Cargo 的分步说明?

ada - 打破测试功能的 Ada 隐私