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

如何在C++中使用DLL 我需要用一个DLL写一个C++程序。我有DLL和头文件,但没有链接器的.a文件。GNU GCC编译器在DLL文件中找不到函数,c++,dll,C++,Dll,我遇到了如下错误: undefined reference to _imp__mbnEthernetOpen@8 如何解决此问题 我上次使用WinAPI已经有很长时间了,不过如果我没记错的话,您需要在运行时使用或动态加载库。之后,您需要获得您感兴趣使用的特定函数的地址;在你的情况下,我想这将是mbnEthernetOpen 在经历了所有这些麻烦之后,您终于可以通过刚刚从DLL获得的函数指针调用mbnEthernetOpen了 编辑:在阅读了这些评论之后,我决定扩展我的答案,以包含一个生

我遇到了如下错误:

    undefined reference to _imp__mbnEthernetOpen@8

如何解决此问题

我上次使用WinAPI已经有很长时间了,不过如果我没记错的话,您需要在运行时使用或动态加载库。之后,您需要获得您感兴趣使用的特定函数的地址;在你的情况下,我想这将是mbnEthernetOpen

在经历了所有这些麻烦之后,您终于可以通过刚刚从DLL获得的函数指针调用mbnEthernetOpen了

编辑:在阅读了这些评论之后,我决定扩展我的答案,以包含一个生成.lib文件的方法

首先,s有一个非常好的书面说明,它贯穿了整个过程。然而,为了清楚起见,我将在这里重复

根据wiki,从“开始”菜单中找到并执行Visual Studio命令提示符,该提示符应位于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
再次确保将临时名称替换为正确的等效名称,另外还要注意该标记符号。在VLC的示例中,这是libvlc,它是示例中每个导出符号的初始部分。现在,由于您向我们展示了一个函数,我不确定这应该是什么,但我相信您可以通过查看导出的符号来了解它

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

请注意,您的/计算机可能因平台而异


好了。这就是从.dll文件生成.lib文件的方法。

自从我上次使用WinAPI以来已经有很长时间了,不过如果我没有记错的话,您需要在运行时使用或动态加载库。之后,您需要获得您感兴趣使用的特定函数的地址;在你的情况下,我想这将是mbnEthernetOpen

在经历了所有这些麻烦之后,您终于可以通过刚刚从DLL获得的函数指针调用mbnEthernetOpen了

编辑:在阅读了这些评论之后,我决定扩展我的答案,以包含一个生成.lib文件的方法

首先,s有一个非常好的书面说明,它贯穿了整个过程。然而,为了清楚起见,我将在这里重复

根据wiki,从“开始”菜单中找到并执行Visual Studio命令提示符,该提示符应位于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
再次确保将临时名称替换为正确的等效名称,另外还要注意该标记符号。在VLC的示例中,这是libvlc,它是示例中每个导出符号的初始部分。现在,由于您向我们展示了一个函数,我不确定这应该是什么,但我相信您可以通过查看导出的符号来了解它

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

请注意,您的/计算机可能因平台而异


好了。这就是从.dll文件生成.lib文件的方式。

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

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


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

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

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



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

函数是否已导出?是否有隐式/静态链接到.dll所需的.lib文件?Windows中的动态链接需要在库路径中找到一些.lib文件。您使用的DLL有附带的吗?您是在什么平台上开发的?a.a听起来像Linux,但是.dll应该在Windows上,而.so在Linux上使用。决定是要使用动态库还是静态库,并说明平台,这样就很容易告诉您要使用的命令。您可以创建一个.lib文件。GCC工具集有这样做的工具。函数是否已导出?是否有隐式/静态链接到.dll所需的.lib文件?Windows中的动态链接需要在库路径中找到一些.lib文件。您使用的DLL有附带的吗?您是在什么平台上开发的?a.a听起来像Linux,但是.dll应该在Windows上,而.so在Linux上使用。决定是要使用动态库还是静态库,并说明平台,这样就很容易告诉您要使用的命令。您可以创建一个.lib文件。GCC工具集有这样的工具。他说编译器找不到函数。LoadLibrary和things在运行时使用。不,通常不需要使用LoadLibrary和GetProcAddress。在一般情况下,您只需链接一个与dll关联的lib文件。@JoséX。OP说他们没有.lib。如果可以的话,您希望避免这样做。创建丢失的.lib文件。如果他试图在运行时动态加载dll,特别是LoadLibrary和GetProcAddress的用途,他将不会得到声明的错误。他得到的错误是编译时错误,这通常意味着他试图链接到库+1@Amrith他说编译器找不到函数。LoadLibrary和things在运行时使用。不,通常不需要使用LoadLibrary和GetProcAddress。在一般情况下,您只需链接一个与dll关联的lib文件。@JoséX。OP说他们没有.lib。如果可以的话,您希望避免这样做。创建丢失的.lib文件。如果他试图在运行时动态加载dll,特别是LoadLibrary和GetProcAddress的用途,他将不会得到声明的错误。他得到的错误是编译时错误,这通常意味着他试图链接到库+1@amrithI认为,通过提供def文件,不使用lib文件是可能的。请看我上面的其他评论。@JoséX。不,你弄错了。.def文件在编译DLL时使用。@David Heffernan:请看这里:@JoséX。那篇文章讨论了导入data@David赫弗南:哦,天哪,我又做了一次……似乎我记错了……很久以前我确实使用了.def文件,但似乎仅仅使用.def文件是不可能链接到dll的。很抱歉弄得一团糟。我相信通过提供def文件,不使用lib文件是可能的。请看我上面的其他评论。@JoséX。不,你弄错了。.def文件在编译DLL时使用。@David Heffernan:请看这里:@JoséX。那篇文章讨论了导入data@David赫弗南:哦,天哪,我又做了一次……似乎我记错了……很久以前我确实使用了.def文件,但似乎仅仅使用.def文件是不可能链接到dll的。抱歉弄得一团糟。