MSys/MinGW 链接到 __imp__ lib/dll 中不存在的链接
MSys/MinGW linking to __imp__ which don't exist in lib/dll
我正在构建一个程序,它使用我编写的库,该库使用作为 .lib 导入文件和 .dll 文件分发的第三方库。我正在使用 CMake 在 MSys 环境中使用 MinGW 进行构建。
当我尝试 link 我的程序时,出现以下错误(为了便于阅读而进行了清理):
ld.exe: libMyLib.a(mylib.cpp.obj): in function `MangledFnName':
src/mylib.cpp:297: undefined reference to `_imp__hasp_get_info@16'
ld.exe: src/mylib.cpp:326: undefined reference to `_imp__hasp_free@4'
在导入文件上使用 objdump(并删除多余的东西)我看到:
[33291](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x001f3cb4 _hasp_get_info@16
[56900](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x001ee4bf _hasp_free@4
注意符号开头缺少 _imp_
。
类似地,但不同的是,当我查看在此环境中正确执行 link 的 FTDI 库时,我看到:
[ 2](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __imp__FT_Write@16
[ 4](sec 2)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 _FT_Write@16
00000002 dir32 __imp__FT_Write@16
开头有_imp_
和没有_imp_
的符号。
更新:我写了一个脚本来从原始导入库中提取符号并使用 dlltool 生成一个新的。它现在 links...但不是 运行。我收到错误:
The procedure entry point _hasp_free could not be located in the dynamic link library.
如果我要求第三方重建他们的图书馆,我必须要求他们做什么才能提供额外的符号?
如何让 ld
查找符号名称而不预先添加 _imp_
?
所以答案是重新生成导入库。 Whosebug 上到处都有各种提示,还有一篇文章 here 关于如何使用 MSVC 工具在 Windows 命令提示符下执行此操作,但为了将来参考,这里有一个 MSys bash脚本:
#!/bin/bash
if [ -z "" ]
then
echo "Syntax: $(basename [=10=]) <import library> <dll file>"
exit
fi
RAW_DLL_NAME=$(basename "" | sed 's#.dll$##')
echo "LIBRARY ${RAW_DLL_NAME}" > tmp.def
echo "EXPORTS" >> tmp.def
for SYMBOL in $(objdump -t "" | grep "sec 1" | grep @ | awk '{ print }' | sed 's#^_##')
do
echo " ${SYMBOL}" >> tmp.def
done
dlltool -k -d tmp.def -l "${RAW_DLL_NAME}.dll.a" -D "${RAW_DLL_NAME}.dll"
rm tmp.def
我的第一次尝试失败了,因为我没有去掉 objdump 生成的符号上的前导下划线,然后在 dlltool 上使用了 --no-leading-underscore
选项。这是错误的。
我还在过滤导出的符号,只包含那些包含“@”的符号。使用 MSVCs dumpbin
实用程序显示了更多可以导出的符号。我过滤了 @
符号,因为我不关心其他符号,它阻止了我获得大量符号,如“__WBPT2660959813”。
我正在构建一个程序,它使用我编写的库,该库使用作为 .lib 导入文件和 .dll 文件分发的第三方库。我正在使用 CMake 在 MSys 环境中使用 MinGW 进行构建。
当我尝试 link 我的程序时,出现以下错误(为了便于阅读而进行了清理):
ld.exe: libMyLib.a(mylib.cpp.obj): in function `MangledFnName':
src/mylib.cpp:297: undefined reference to `_imp__hasp_get_info@16'
ld.exe: src/mylib.cpp:326: undefined reference to `_imp__hasp_free@4'
在导入文件上使用 objdump(并删除多余的东西)我看到:
[33291](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x001f3cb4 _hasp_get_info@16
[56900](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x001ee4bf _hasp_free@4
注意符号开头缺少 _imp_
。
类似地,但不同的是,当我查看在此环境中正确执行 link 的 FTDI 库时,我看到:
[ 2](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __imp__FT_Write@16
[ 4](sec 2)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 _FT_Write@16
00000002 dir32 __imp__FT_Write@16
开头有_imp_
和没有_imp_
的符号。
更新:我写了一个脚本来从原始导入库中提取符号并使用 dlltool 生成一个新的。它现在 links...但不是 运行。我收到错误:
The procedure entry point _hasp_free could not be located in the dynamic link library.
如果我要求第三方重建他们的图书馆,我必须要求他们做什么才能提供额外的符号?
如何让 ld
查找符号名称而不预先添加 _imp_
?
所以答案是重新生成导入库。 Whosebug 上到处都有各种提示,还有一篇文章 here 关于如何使用 MSVC 工具在 Windows 命令提示符下执行此操作,但为了将来参考,这里有一个 MSys bash脚本:
#!/bin/bash
if [ -z "" ]
then
echo "Syntax: $(basename [=10=]) <import library> <dll file>"
exit
fi
RAW_DLL_NAME=$(basename "" | sed 's#.dll$##')
echo "LIBRARY ${RAW_DLL_NAME}" > tmp.def
echo "EXPORTS" >> tmp.def
for SYMBOL in $(objdump -t "" | grep "sec 1" | grep @ | awk '{ print }' | sed 's#^_##')
do
echo " ${SYMBOL}" >> tmp.def
done
dlltool -k -d tmp.def -l "${RAW_DLL_NAME}.dll.a" -D "${RAW_DLL_NAME}.dll"
rm tmp.def
我的第一次尝试失败了,因为我没有去掉 objdump 生成的符号上的前导下划线,然后在 dlltool 上使用了 --no-leading-underscore
选项。这是错误的。
我还在过滤导出的符号,只包含那些包含“@”的符号。使用 MSVCs dumpbin
实用程序显示了更多可以导出的符号。我过滤了 @
符号,因为我不关心其他符号,它阻止了我获得大量符号,如“__WBPT2660959813”。