我需要使用 DLL 编写一个 c++ 程序。我有 DLL 和头文件,但没有链接器的 .a 文件。GNU GCC 编译器在 DLL 文件中找不到函数。
我收到如下错误:
undefined reference to _imp__mbnEthernetOpen@8
我该如何解决这个问题。
看起来您正在尝试编译依赖于另一个共享库的程序。要在 windows 上编译支持这个库,你通常需要 3 件事:
您在评论中说您所拥有的只是头文件和 dll 文件。这意味着您要么缺少 lib 二进制文件并且需要查找/重新编译库,要么您试图在运行时动态加载 DLL 并使用函数指针来调用不同的函数(正如 Goksel 在他的回答中提到的那样)。您的错误表明您正在尝试执行第一个选项(链接到共享库)。
如果要在编译时动态链接到库,则需要有 lib 文件。
自从我上次使用 WinAPI 以来已经有很长一段时间了,但如果我没记错的话,你需要在运行时使用 或 动态加载LoadLibrary
库LoadLibraryEx
。之后,您需要获取您有兴趣使用的特定功能的地址GetProcAddress
;在你的情况下,这将是mbnEthernetOpen
(我猜)。
经过这么多的麻烦,你终于可以mbnEthernetOpen
通过你刚刚从DLL中获得的函数指针来调用了。
编辑:阅读评论后,我决定扩展我的答案以包含生成.lib
文件的方法。
首先,VLC的wiki有一篇写得很好的文章,它彻底完成了整个过程。但是,为了清楚起见,我将在这里重复一遍。
从开始菜单找到并执行Visual Studio Command Prompt,根据 wiki 这应该在Microsoft Visual Studio条目下。
在Visual Studio 命令提示符上执行此命令行以从 DLL 文件中提取符号:dumpbin /exports input.dll > exports.def
确保分别将input.dll
和替换exports.def
为正确输入和输出文件的路径。
此时,您可以启动文本编辑器并编辑新生成的.def
文件,使其看起来像这样:
EXPORTS
libvlc_add_intf
libvlc_audio_get_channel
libvlc_audio_get_mute
libvlc_audio_get_track
libvlc_audio_get_track_count
libvlc_audio_get_track_description
libvlc_audio_get_volume
…
显然,对于您的 DLL,导出符号的名称会有所不同。
但是,无论出于何种原因,如果您不想手动执行所有这些操作,在 VLC wiki 上写这篇文章的帅哥们想出了一个可以.def
自动生成文件的一次性命令行:
echo EXPORTS > output.def
for /f "usebackq tokens=4,* delims=_ " %i in (`dumpbin /exports input.dll`) do if %i==tag echo %i_%j >> exports.def
再次确保将临时名称替换为更正后的等效名称,另外注意该tag
符号。在 VLC 的示例中,这是libvlc
,它是示例中每个导出符号的初始部分。现在,由于您向我们展示了一个函数,我不确定这应该是什么,但我相信您可以通过查看导出的符号来弄清楚。
最后,.lib
从这些导出的符号生成文件,这些符号现在在您的.def
文件中:
lib /def:exports.def /out:library.lib /machine:x86
请注意,您/machine
的平台可能会有所不同。
你去吧。这就是.lib
从文件生成.dll
文件的方式。