pragma export 函数在 Ada 可执行文件中不是外部的
pragma export function is not external in Ada executable
我需要一个 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,但我的 linker 似乎太老了,不知道这个开关。
另一个有前途的选项是将 -shared 添加到 link 步骤,但是虽然现在公开了函数,但它还将输出文件更改为 DLL(扩展名为 .EXE (!)) ,所以这也没有用。
在我升级我的工具链之前,是否有另一个 linker switch 我可以尝试,或者任何其他建议?
您需要告诉链接器从可执行文件中导出符号。 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 中的 return 类型。
- 调用约定必须匹配。 Ada 中的
Stdcall
匹配 C++ 中的显式 __stdcall
。如果 C++ 代码中没有 __stdcall
,请改用 Ada 中的 C
调用约定。
我需要一个 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,但我的 linker 似乎太老了,不知道这个开关。
另一个有前途的选项是将 -shared 添加到 link 步骤,但是虽然现在公开了函数,但它还将输出文件更改为 DLL(扩展名为 .EXE (!)) ,所以这也没有用。
在我升级我的工具链之前,是否有另一个 linker switch 我可以尝试,或者任何其他建议?
您需要告诉链接器从可执行文件中导出符号。 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 中的 return 类型。 - 调用约定必须匹配。 Ada 中的
Stdcall
匹配 C++ 中的显式__stdcall
。如果 C++ 代码中没有__stdcall
,请改用 Ada 中的C
调用约定。