【问题标题】:MSys/MinGW linking to __imp__ which don't exist in lib/dllMSys/MinGW 链接到 lib/dll 中不存在的 __imp__
【发布时间】:2021-08-19 09:31:59
【问题描述】:

我正在构建一个程序,该程序使用我编写的库,该库使用作为 .lib 导入文件和 .dll 文件分发的第三方库。我正在使用 CMake 在 MSys 环境中使用 MinGW 进行构建。

当我尝试链接我的程序时,我收到以下错误(已清理以提高可读性):

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_

类似但不同的是,当我查看在此环境中正确链接的 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_的符号。


更新:我编写了一个脚本来从原始导入库中提取符号并使用 dlltool 生成一个新的。它现在链接......但不运行。我得到了错误:

The procedure entry point _hasp_free could not be located in the dynamic link library.

如果我要求第三方重建他们的库,我必须要求他们做什么才能提供额外的符号?

如何告诉ld 查找符号名称而不添加_imp_

【问题讨论】:

  • dll_export库函数了吗?
  • @ssbssa 问题库是第三方库。不是我的代码,不是我的构建系统。所以不,我没有,因为我做不到。但是库函数显然是导出的,因为它们是在我在 DLL 上使用 dumpbin \exports 时找到的。
  • 如果第三方.lib 不是使用相同的编译器和版本构建的,您可能无法使用它。尝试后期绑定到 DLL(希望作者没有在 DLL 中做不可移植的事情),如果可行,那么您可能可以制作一个新的导入库
  • 如何进行后期绑定?您的意思是在运行时将其显式加载为动态库吗?

标签: c linker mingw


【解决方案1】:

所以答案是重新生成导入库。 StackOverflow 上到处都有各种提示,还有一篇文章 here 介绍了如何在 Windows 命令提示符下使用 MSVC 工具进行操作,但为了将来参考,这里有一个 MSys bash 脚本:

#!/bin/bash

if [ -z "$2" ]
then
    echo "Syntax: $(basename $0) <import library> <dll file>"
    exit
fi

RAW_DLL_NAME=$(basename "$2" | sed 's#.dll$##')

echo "LIBRARY ${RAW_DLL_NAME}" > tmp.def
echo "EXPORTS" >> tmp.def

for SYMBOL in $(objdump -t "$1" | grep "sec  1" | grep @ | awk '{ print $9 }' | 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”这样的符号。

【讨论】:

    猜你喜欢
    • 2016-07-13
    • 1970-01-01
    • 2020-11-14
    • 2011-01-29
    • 1970-01-01
    • 2022-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多