如何在Visual Studio C++中使用第三方DLL文件?

84

我知道我需要使用LoadLibrary(),但是为了使用第三方DLL文件,我还需要采取哪些步骤呢?

我直接跳入C++,这是唯一的部分我不太明白(作为一名Java程序员)。我正在探索如何使用Qt库和tesseract-ocr,然而这个过程对我来说毫无意义,而且很难通过谷歌了解。

我该如何告诉编译器我正在使用的函数?是否应该有来自第三方供应商的include文件?


你知道如何在Visual Studio 2012中为C++添加第三方dll文件吗?请帮帮我。 - afzalex
6个回答

79

众所周知,使用LoadLibrary方法是一种很困难的方式,几乎从不必要。

这个DLL应该带有一个用于链接的.lib文件,以及一个或多个需要#include到你的代码中的头文件。这些头文件将定义你可以从DLL中使用的类和函数原型。即使你使用LoadLibrary,你也需要这些东西。

要链接库,你可能需要将.lib文件添加到项目配置中的链接器/输入/附加依赖项下。


1
谢谢,其他的答案也很好(对我也很有用),但这个恰好解释了我正在寻找的东西。 - Zombies
2
@advocate,"常规"选项卡上有一个名为“附加库目录”的条目。我不知道微软为什么要将它们分开。 - Mark Ransom
我确实这样做了,但我仍然收到链接器错误。我已经把我的.dll文件放到了C:/Windows中。我做错了什么? - Bart
@anon58192932 Visual Studio允许在“附加依赖项”参数中使用完整的库路径。 - Ark-kun
1
@darkgaze 你可以使用 #import 来自动生成并包含一个 DLL 的头文件。编译器需要知道所有函数的声明,以便能够构建调用代码。 - Mark Ransom
显示剩余3条评论

75
为了将第三方DLL文件引入到我的VS 2008 C++项目中,我做了以下操作(您应该能够将其翻译成2010、2012等)...
我将头文件放入我的解决方案与其他头文件中,并更改了我的代码以调用DLL函数(否则我们为什么要这样做呢?): ^) 然后我更改了构建,将LIB代码链接到我的EXE中,将DLL复制到正确位置,并在执行"清理"操作时进行清理-我会在下面解释这些更改。
假设您有两个第三方DLL文件A.DLL和B.DLL,每个都有一个存根LIB文件(A.LIB和B.LIB)和头文件(A.H和B.H)。
1. 在您的解决方案目录下创建一个"lib"目录,例如使用Windows资源管理器。 2. 将第三方.LIB和.DLL文件复制到此目录中。
(对于您使用的每个源生成目标,都必须进行下一组更改(调试、发布)。)
1. 使您的EXE依赖于LIB文件 - 转到"配置属性"-> "链接器"-> "输入"-> "其他依赖项",并逐个列出您的.LIB文件,以空格分隔:A.LIB B.LIB。 - 转到"配置属性"-> "常规"-> "附加库目录",并将您的"lib"目录添加到任何已经存在的目录中。条目由分号分隔。例如,如果您已经有$(SolutionDir)fodder,则将其更改为$(SolutionDir)fodder;$(SolutionDir)lib以添加"lib"。
2. 强制DLL文件被复制到输出目录 - 转到"配置属性"-> "生成事件"-> "后期生成事件" - 将以下命令行放入命令行中(有关开关含义,请参见DOS窗口中的"XCOPY /?"):

将DLL复制到目标目录

  • 在构建中不应排除,选择No。 单击确定
  • 告诉VS在清理输出文件夹时清理DLL:

    • 转到配置属性 -> 常规 -> 删除扩展名,在“...”上单击; 将*.dll添加到列表的末尾,然后单击确定

  • 2
    我正在尝试使用您的方法来使用第三方dll。我正在使用Visual Studio 2012旗舰版,但在“配置属性->常规”选项卡中没有“附加库目录”。请帮助我。 - afzalex
    8
    应该是 配置属性 -> 链接器 -> 常规 -> 附加库目录 - Colin Robertson
    @afzalex,你可以在“配置属性”>“VC++目录”>“库目录”中找到它。这是一次世代的变革 ;) - Bokhari
    第二步中引号位置错误。请使用:XCOPY "$(SolutionDir)\lib\*.DLL" "$(TargetDir)" /D /K /Y - Tristan CHARBONNIER
    有趣。我很确定我从我的工作配置中复制/粘贴了XCOPY命令。你是说引号错放位置导致它对你不起作用,还是只是猜测? - rich p
    谢谢,第二点解决了我遇到的问题,即程序在运行时无法找到“.dll”,尽管它编译得很好! - EM-Creations

    26
    这是在Windows中使用DLL文件的两种方式:
    1. 使用带有相关头文件的存根库(.lib)。当您将可执行文件与此lib文件链接时,程序启动时会自动加载DLL文件。

    2. 手动加载DLL文件。这通常是您在开发插件系统时想要做的事情,其中有许多DLL文件实现共同的接口。有关此更多信息,请查看LoadLibraryGetProcAddress的文档。

    对于Qt,我会怀疑是否有可用的头文件和静态库,您可以将其包含并链接到项目中。

    还有第三种方式,类似于您的第一种方式,使用/MT开关,它将静态链接您的库。优点是没有动态链接开销。但是,如果您还使用/clr开关,则无法使用此选项。 - Abel
    2
    这仅适用于标准库。对于自定义库(第三方),除非有人明确构建了一个您可以链接的静态版本,否则您无法静态链接dll。 - Laserallan
    @Laserallan 我正在开发一个DLL项目,但是当我构建它时,它只创建了dlllib文件,并未创建一个includes目录。我该如何将我的头文件包含进项目中呢? - mrid
    dll/import library是链接器的输出。在提供所需的包含文件时,您需要确保它们一起分发。如何做取决于您的构建系统,但如果使用cmake,请查看install命令系列,这将帮助您以结构化的方式确定要分发的重要文件。 - Laserallan

    8
    为了使用动态链接的Qt,您需要在以下位置指定lib文件(通常为“Debug”配置中的qtmaind.lib、QtCored4.lib和QtGuid4.lib):
    属性» 链接器» 输入» 附加依赖项
    您还需要指定库所在的路径,即在以下位置:
    属性» 链接器» 常规» 附加库目录
    并且您需要通过将它们存储在与您的.exe文件相同的文件夹或路径上的文件夹中,使相应的.dll在运行时可访问。

    3

    如果你想在运行时动态地绑定并解析导入的函数,那么只需要使用LoadLibrary。使用第三方dll最简单的方法是链接一个.lib文件。


    回答你的编辑:

    是的,第三方API应该包含一个包含实现和声明所需类型的dll和/或lib文件。无论你使用哪种方法,你都需要了解类型定义。对于LoadLibrary,你需要定义函数指针,因此你也可以编写自己的头文件。基本上,只有当你想要延迟绑定时才需要使用LoadLibrary。这样做的一个有效原因是,你不确定目标PC上是否有该dll。


    2
    如果您需要使用它,那么第三方库应该有一个*.lib文件和一个*.dll文件。您只需要将*.lib添加到项目“链接器”选项的输入文件列表中即可。
    这个*.lib文件不一定是一个包含代码的“静态”库:相反,*.lib可以只是一个将您的可执行文件与DLL链接起来的文件。

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接