2009-07-14 78 views
13

我是C++的新手,有些东西我完全没有得到。在C#中,如果我想使用外部库,例如log4net,我只需添加一个对log4net DLL的引用,并且它的成员会自动提供给我(以及IntelliSense中)。我如何在非托管C++中执行此操作?如何在C++中“添加引用”

回答

23

除了.dll以外,库经常会带有1)头文件(.h)和2).lib文件。

头文件包含在您的代码中,以便您访问库中的类型和函数声明。

.lib链接到您的应用程序中(项目属性 - >链接器 - >输入,附加依赖项)。

的的.lib文件通常包含简单的存根自动加载的dll和转发功能调用它。

如果你没有的.lib文件,你就不是必须使用LoadLibrary函数来动态加载DLL。

+0

比我的回答更彻底。我还要补充一点,如果你使用的是LoadLibrary,那么你不能简单地通过名字来调用函数。你需要做后期绑定。 – 2009-07-14 20:14:25

+1

我看到我再次不完整。 LoadLibrary返回一个可以传递给GetProcAddress的句柄,它给你一个真正的指针。你也可以选择调用FreeLibrary来卸载它。 (我继续并删除了我原来的答案。) – 2009-07-14 20:18:06

+0

@Steven:的确,我认为如果他确实需要使用LoadLibrary,我只会给他一个出发点,而不会陷入(很多)粗陋的细节之中。 – jalf 2009-07-14 20:23:06

0

您需要做的第一件事是#include描述该库中可用函数的头文件。

该库的实际代码将在2的一个地方:

  1. 静态库(.LIB)
  2. 一个DLL文件(.dll)

根据如何库的代码是给你的(如.lib文件或.dll),你必须:

  • #pragma comment(lib,“libraryname.lib”)if它是一个.LIB
  • LoadLibrary如果一个.dll

有时包随附了,你需要链接到的.lib文件和.dll文件。在这种情况下,你不需要调用LoadLibrary,你只需要#pragma comment(lib,“libaryfile.lib”),因为在这种情况下.lib将你链接到.dll。

一个非常重要的细节是将DLL放在应用程序可以找到它的地方。 Charles Petzold说:

当Windows需要在运行需要它的程序之前加载DLL模块时,库文件必须存储在包含.EXE程序,当前目录,Windows系统目录, Windows目录或通过MS-DOS环境中的PATH字符串访问的目录。 (该目录中查找的顺序。) Programming windows, 5th ed MSDN

我不推荐使用项目属性菜单链接,因为它并不像看到哪些库要链接到。

See also

+0

这不回答这个问题。 – 2009-07-14 19:27:18

+0

这确实回答了现在的问题,但不正确。正如jalf所指出的那样,你通常会链接到导入库(使用编译指示或以其他方式将其添加到lib.exe关闭的命令行中)。使用LoadLibrary是后期绑定的选择。 – 2009-07-14 20:16:31

4

C++没有在你想的感库。它有一个头文件,你的文件名为#include,它有一些链接器处理的库,包含编译后的代码。您需要将库(.LIB文件)添加到链接器设置。

在Windows上,如果您使用的是一个DLL,理想情况下应该有一个.LIB文件与它一起使用,称为DLL的导入库,然后将该.LIB文件添加到链接器设置中。

9

基本概念如下: 库有两种类型:static & dynamic。它们之间的区别在于,链接构建步骤中的静态库将它们的编译代码嵌入到可执行文件(或dll)中;动态库只是嵌入指向函数的指针,以及在程序加载时应该加载一些DLL的指令。这是由链接器为您实现的。

现在你可以决定这两个,你要使用。 DLL有许多优点和缺点。如果开发一个巨大的应用程序,可能值得考虑使用延迟加载的DLL而不是静态库。有些库只是作为DLL传递给你,你别无选择。无论如何,初学者最简单的方法就是使用静态库。这会让你的部署和测试变得更容易,因为在处理DLL时必须确保它们在运行时被发现(即使在使用调试器时),这涉及到复制一个目录中的所有内容或处理路径变量。

通常一个DLL提供商(如果意图是,你应该能够处理库)提供您一个头文件(S)和包含来电到所需的DLL中的.lib。一些供应商(例如boost)只要求你包含头文件,并且lib自动链接到你的可执行文件(可以通过编译器prorietary pragma指令来实现)。如果不是这种情况,您必须进入C++项目的项目设置(project properites/Configuration Properties/Linker/Input),并将lib文件名输入到“Additional Dependencies”行中。 iced.lib iceutild.lib。您也可以在其中放置完全限定的路径名​​称。请注意,您必须为两种配置(Debug,Release)输入lib文件名。这是您对静态库和Dll的平等操作。 DLL需要一个DLL库的唯一区别在于你的app-directory或其中一个路径目录。

这一步后,如果您尝试链接不兼容的库,你仍然可能会得到编译器错误。有很多原因,为什么他们可能不兼容。但尝试首先连接这个库,看看是否有用。如果不是,请在此处再次发布您的错误;)

包含文件(s)被用于包含在您希望使用smth的地方。从lib。只需包含它,编译器就会知道这些符号必须来自另一个(编译的)编译单元(编译后的cpp-file =>目标文件)或.lib。它会查找并通知您是否找不到所需的符号。

好运,
Ovanes

附:这一开始可能很难,但是当你习惯它时,它会很容易。