2

我需要使用 DLL 编写一个 c++ 程序。我有 DLL 和头文件,但没有链接器的 .a 文件。GNU GCC 编译器在 DLL 文件中找不到函数。

我收到如下错误:

    undefined reference to _imp__mbnEthernetOpen@8

我该如何解决这个问题。

4

2 回答 2

3

看起来您正在尝试编译依赖于另一个共享库的程序。要在 windows 上编译支持这个库,你通常需要 3 件事:

  • 头文件
  • 用于编译时链接的 lib 二进制文件
  • 用于运行时执行的 dll 二进制文件(必须在运行时找到并加载的二进制文件的路径中) 如果您静态链接 .lib 文件,则可选

您在评论中说您所拥有的只是头文件和 dll 文件。这意味着您要么缺少 lib 二进制文件并且需要查找/重新编译库,要么您试图在运行时动态加载 DLL 并使用函数指针来调用不同的函数(正如 Goksel 在他的回答中提到的那样)。您的错误表明您正在尝试执行第一个选项(链接到共享库)。

如果要在编译时动态链接到库,则需要有 lib 文件。

于 2013-08-26T15:54:44.447 回答
1

自从我上次使用 WinAPI 以来已经有很长一段时间了,但如果我没记错的话,你需要在运行时使用 或 动态加载LoadLibraryLoadLibraryEx。之后,您需要获取您有兴趣使用的特定功能的地址GetProcAddress;在你的情况下,这将是mbnEthernetOpen(我猜)。

经过这么多的麻烦,你终于可以mbnEthernetOpen通过你刚刚从DLL中获得的函数指针来调用了。

编辑:阅读评论后,我决定扩展我的答案以包含生成.lib文件的方法。

首先,VLCwiki有一篇写得很好的文章,它彻底完成了整个过程。但是,为了清楚起见,我将在这里重复一遍。

  1. 开始菜单找到并执行Visual Studio Command Prompt,根据 wiki 这应该在Microsoft Visual Studio条目下。

  2. 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,它是示例中每个导出符号的初始部分。现在,由于您向我们展示了一个函数,我不确定这应该是什么,但我相信您可以通过查看导出的符号来弄清楚。

  3. 最后,.lib从这些导出的符号生成文件,这些符号现在在您的.def文件中: lib /def:exports.def /out:library.lib /machine:x86

    请注意,您/machine的平台可能会有所不同。

你去吧。这就是.lib从文件生成.dll文件的方式。

于 2013-08-26T15:00:29.610 回答