如何使用dll

CAA*_*A14 1 c++ dll libraries

我最近在尝试使用 gdi+ 时感到非常困惑,因为 sdk 文件只有三个文件,其中之一是 .dll 文件。我认为我需要加载 dll,并且由于我从未被教导或接触过此类东西,不用说我很困惑。(现在看来,安装还将 gdi+ sdk 文件放入 VS 查找标准文件的文件夹中(通过 <> 包含的内容,但仍然让我对 dll 在那里做什么一无所知)。

我研究并得到了似乎表明以下内容的解释:

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

要使用它,您必须使用 loadlibrary,然后使用 getprocaddress 来基本上获取指向特定的指针(或我不清楚的东西)要使用它,您必须使用 loadlibrary,然后使用 getprocaddress 来基本上获取指向 dll 中

你看,我的印象是,库基本上是你要重用的代码,同样的概念,但更有效的形式是简单地创建有用方法和类的 .cpp 文件,然后包含它们。

据我所知,这种假设是不正确的,我希望有人了解 .lib 和 .dll 库的内部和外部情况,如果愿意的话可以解释一下。

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

Ane*_*dar 6

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

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