我有一个使用 Visual Studio 编译的 Visual C++ 项目。该程序导入了我在 Ubuntu 上使用 MinGW x64 交叉编译器创建的 2 个 DLL。对于这个问题,我创建了 2 个包含虚假函数的人为 DLL(这些人为 DLL 仍然会导致同样的问题)。我们将它们称为
test1.dll
和 test2.dll
。
test1.c
:
__declspec(dllexport) int test_func_add(int a, int b) { return a + b; }
__declspec(dllexport) unsigned long test_func_ptr(void* ptr_to_anything) { return (unsigned long)ptr_to_anything; }
test2.c
:
__declspec(dllexport) int test_func_mult(int a, int b) { return a * b; }
__declspec(dllexport) double test_func_div(double dividend, double divisor) { return dividend / divisor; }
这两个 C 文件都是使用完全相同的 MinGW 命令编译的(% 只是命令中使用的数字的占位符,1 或 2):
x86_64-w64-mingw32-gcc test%.c -o test1.dll -shared -fvisibility=hidden -Wl,--out-implib,test%.lib
对生成的
dumpbin /exports
和 test1.dll
使用 test2.dll
分别产生以下结果:
ordinal hint RVA name
// Look at the "Edit" section at the bottom of the question
1 0 000013D0 test_func_add
2 1 000013E4 test_func_ptr
ordinal hint RVA name
1 0 000013E3 test_func_div
2 1 000013D0 test_func_mult
以及生成的导入库(分别为
test1.lib
和 test2.lib
):
ordinal name
// Look at the "Edit" section at the bottom of the question
test_func_ptr
test_func_add
ordinal name
test_func_mult
test_func_div
看起来一切都很好?
但是,当我通过导入库将这些 DLL 链接到我的 Visual C++ 应用程序并在生成的可执行文件上运行
dumpbin /imports
时,我得到以下结果:
test1.dll
140021268 Import Address Table
1400C66C8 Import Name Table
0 time date stamp
0 Index of first forwarder reference
1 test_func_div
1 test_func_add
2 test_func_ptr
2 test_func_mult
test2.dll
140021268 Import Address Table
1400C66C8 Import Name Table
0 time date stamp
0 Index of first forwarder reference
1 test_func_div
1 test_func_add
2 test_func_ptr
2 test_func_mult
它试图从两个 DLL 导入相同的函数。显然,它会在一个 DLL 中查找某个函数,但没有找到它,并抛出一个“无法找到入口点”错误,即使该函数确实存在 - 就在“其他”DLL 中。
最后,这是我在 Visual C++ 项目中声明这些外部函数的方式:
extern "C" __declspec(dllimport) int test_func_add(int a, int b);
extern "C" __declspec(dllimport) unsigned long test_func_ptr(void* ptr_to_anything);
extern "C" __declspec(dllimport) int test_func_mult(int a, int b);
extern "C" __declspec(dllimport) double test_func_div(double dividend, double divisor);
为什么会发生这种情况? MinGW 和 MSVC 项目不兼容吗?我的流程有问题吗?任何帮助将不胜感激。
编辑:回顾
dumpbin /exports
的输出,我注意到与相应的DLL相比,导入库上的函数顺序是相反的。这可能是问题的一部分吗?我将其与 opencv_world460.dll
和
opencv_world460.lib
(我的程序使用 OpenCV)的顺序进行了比较,导入库和 DLL 中函数的顺序是相同。顺便说一句,我已经看过这篇文章。 OP 下载了与 DLL 不同版本的导入库,这并不能回答我的问题,因为我创建了