gpt4 book ai didi

c++ - 如何静态链接到由序号导出的 DLL 函数?

转载 作者:太空狗 更新时间:2023-10-29 20:34:32 24 4
gpt4 key购买 nike

比如说,如果一个 DLL 有一个函数:

int TestFunc01(int v)
{
WCHAR buff[256];
::StringCchPrintf(buff, _countof(buff), L"You passed a value of %d", v);
return ::MessageBox(NULL, buff, L"Test Dll Message", MB_OK | MB_ICONINFORMATION);
}

仅按其序数值导出(以下为.def文件):

LIBRARY   DllName
EXPORTS
TestFunc01 @1 NONAME

所以现在当我想从另一个模块静态链接到该函数时,如果该函数是按名称导出的,我会执行以下操作:

extern "C" __declspec(dllimport) int TestFunc01(int v);

int _tmain(int argc, _TCHAR* argv[])
{
TestFunc01(123);
}

但我如何仅通过其序数值静态链接到它呢?

附言。我正在使用 Visual Studio C++ 编译器和链接器。

最佳答案

But how do I statically link to it only by its ordinal value?

完全相同,当函数按名称导出时 - 没有任何区别。在这两种情况下,您都需要两件事——正确声明函数:

extern "C" __declspec(dllimport) int /*calling convention*/ TestFunc01(int v);

和 lib 文件,包含在链接器输入中。

当您将 somename.def 文件包含到 visual studio 项目时,它会自动将 /def:"somename.def" 选项添加到链接器(否则您需要手动添加它选项)。生成的 lib 文件将包含 __imp_*TestFunc01* 符号 - 在适当的地方 * 将根据 cc++ 符号和调用约定进行不同的修饰,以防 x86

从另一方面来说,当你调用函数时,带有 __declspec(dllimport) 属性。编译器 (CL) 将生成 call [__imp_*TestFunc01*] - 所以引用 __imp_*TestFunc01* 符号(再次 * 在实际位置装饰)。链接器将搜索 __imp_*TestFunc01* 符号并在 lib 文件中找到它。

NONAME 选项对于此过程无关紧要 - 这只会影响 PE 中此函数的 IAT/INT 条目的形成方式(将按名称或序号导入)

请注意,如果我们仅通过 link.exe/lib/def:somename.def 将生成的 lib 文件与 def 文件分开 - 链接器将没有正确的导出函数声明(def 文件仅包含名称而不调用约定和 c 或 c++ 名称) - 因此它始终将被视为符号 extern "C"__cdecl


在具体情况下可见,在 dll 函数中实现为 int TestFunc01(int v) - 所以没有 extern "C" - 因为 lib 文件中的结果将是类似的符号__imp_?TestFunc01@@YAHH@Z(我假设 __cdeclx86),但在与 一起使用的另一个模块函数中extern "C" - 因此链接器将搜索 __imp__TestFunc01 并且当然找不到它,因为它不存在于 lib 文件中。因为这样,当我们导出/导入某些符号时 - 它必须为两个模块声明相等。最好在具有显式调用约定的单独 .h 文件中声明它

关于c++ - 如何静态链接到由序号导出的 DLL 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48047497/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com