如何使用DLL

时间:2016-02-15 03:28:14

标签: c++ dll libraries

我最近在尝试使用gdi +时非常困惑,因为sdk文件中只有三个文件,其中一个是.dll文件。我以为我需要加载dll,因为我从未被教过或接触过这样的东西,不用说我很困惑。 (现在似乎安装也把gdi + sdk文件放在VS寻找标准文件的文件夹中(通过<>包含的东西,仍然让我对dll在那里做的事情毫无头绪)。

我研究并得到了一个似乎暗示如下的解释:

.dll文件是一个文件,它的代码在执行时被加载到内存中,通过指针引用内存而不是像标准的lib加载那样复制代码来节省时间。这也允许在不更改可执行文件的情况下更改dll的多功能性。

要使用它,你必须使用loadlibrary,然后getprocaddress基本上得到一个指针(或某些东西,我不清楚)到特定的元素,如类或函数, dll。

你知道,我的印象是一个库基本上是你要重用的代码,相同的概念,但是一个更有效的形式只是简单地生成有用的方法和类的.cpp文件然后包含它们。 / p>

据我所知,这个假设是不正确的,我希望有人知道这个.lib和.dll库的内部和外部的东西,如果他们愿意解释它。

请记住,我目前对dll或lib目的的理解是重用代码。创建一个包含类和方法的文件,然后将其导入以使用它。在这个意义上,我对图书馆非常缺乏经验。

2 个答案:

答案 0 :(得分:2)

.dll和.lib正如您所说的重用代码的选项。 .dll称为动态库,因为库是在运行时加载的,而.lib是一个静态库,在编译时加载并放入程序中。我知道使用这些库的三个选项:

  • 您直接使用.dll,这意味着使用LoadLibrary()将.dll加载到内存中,然后使用GetProcAdress获取函数指针(基本上是变量中的内存地址,但您可以像功能一样使用它。这里的问题是:你需要知道函数的错位名称(mangled =编译器生成的函数重载和类似的唯一名称),你需要知道函数参数和返回值。
  • 您使用静态库(.lib)。这意味着您将库的头文件包含在项目中,它告诉编译器函数名称(没有修改),它们的参数和返回值,就像使用不同.cpp文件中定义的函数一样。但随后库的代码被复制到您的程序中,这增加了它的大小,如果库已更新,您必须重新编译您的程序。
  • 某些SDK包含预构建(或易于构建)的静态库文件(.lib),它们实际上只包含存根代码,然后在程序开始时加载包含实际代码的.dll。这将为您提供最好的两种可能性,因为在运行时仍然加载库时,您根本不必乱用名称修改/函数指针。这也意味着只需在库的API(=标题)更改后重新编译程序。
  • 此列表中第一个示例涉及的步骤可由主机操作系统处理:如果您的编译器是智能的,它可以检测您正在调用的外部函数,并在"导入表&中声明它们#34;直接在输出可执行文件中。当操作系统加载你的程序时,它可以为你链接导入表 - 这确实减慢了程序加载时间(如果从未调用某些函数可能会浪费时间) - 或者如果找不到依赖项文件则导致程序无法加载在HDD上(如果你使用LoadLibrary,你可能会优雅地失败),但它确实显着减少了程序员的负担。
  • 还有COM(或CORBA),可以看作此列表中第一个示例的扩展; COM允许公开和导出整个对象,而不仅仅是自由函数。这是一种功能强大的方法,可以实现可重用的用户界面小部件和数据库访问代码。缺点是组件容器DLL必须符合定义的应用程序二进制接口,并且需要大量的工作和其他文件,如IDL(接口定义语言)。
    • 附注:像Java和CLR这样的运行时为组件提供类似COM的方式来声明它们包含的类和组件,并允许其他程序在运行时引用和使用这些对象而无需任何编译时链接。 Microsoft Windows 8.0(及更高版本)使用" Windows运行时"将此方法概括为更多可执行二进制类型。其中一个简单的元数据文件(.winmd)基本上用作一种"导出列表"。它可以被认为是一种类固醇" COM。或者"面向21世纪的COM"如果你感觉很卑鄙。

答案 1 :(得分:1)

要使用DLL,您:

    编译时
  1. #include头文件。
  2. 在链接过程中包含.lib文件(' implib'),以便链接器知道符号是从dll运行时到来的。
  3. 安排.dll文件出现在PATH环境变量中包含的目录中。
  4. 请注意,在某些版本的Windows中,此过程因SxS注意事项而变得复杂,您需要一个清单。您可以自己查找SxS及相关问题。