我有一个使用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命令编译的:
x86_64-w64-mingw32-gcc test1.c -o test1.dll -shared -fvisibility=hidden -Wl,--out-implib,test1.lib
x86_64-w64-mingw32-gcc test2.c -o test2.dll -shared -fvisibility=hidden -Wl,--out-implib,test2.lib
型
在结果test1.dll
和test2.dll
上使用dumpbin /exports
分别产生以下结果:
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中函数的顺序是相同的。
顺便说一下,我已经看过this post了。OP下载了一个与DLL不同版本的导入库,这并没有回答我的问题,因为我创建了导入库和DLL。
1条答案
按热度按时间nhjlsmyf1#
事实证明,这个问题确实与MinGW生成的导入库有关。我通过使用Microsoft的
lib
工具来生成导入库来解决这个问题。这需要告诉MinGW链接器输出一个.def
文件,可以使用以下命令完成:字符串
然后,在Visual Studio终端中(将
.dll
和.def
文件复制到Windows后):型
这些命令将生成实际上与MSVC环境一起工作的导入库。需要说明的是,MinGW生成的动态库是很好的。我只需要使用官方的Microsoft工具生成导入库。