如何使用 dll

How to use a dll

本文关键字:dll 何使用      更新时间:2023-10-16

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

我研究了一下,得到了一个解释,似乎暗示了以下内容:

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

要使用它,您必须使用 loadlibrary,然后使用 getprocaddress 基本上获取指向 dll 中特定元素(例如类或函数(的指针(或其他东西,我不清楚(。

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

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

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

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

    您可以直接使用 .dll,
  • 这意味着使用 LoadLibrary() 将.dll加载到内存中,然后使用 GetProcAddress 获取函数指针(基本上是变量中的内存地址,但您可以像使用函数一样使用它(。这里的问题是:你需要知道函数的损坏名称(mangled = 编译器为函数重载和类似生成的唯一名称(,并且你需要知道函数参数和返回值。
  • 使用静态库 (.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"。

若要使用 DLL,请:

  1. 编译时#include头文件。
  2. 在链接过程中包括.lib文件("implib"(,以便链接器知道符号在运行时来自 DLL。
  3. 安排.dll文件存在于PATH环境变量中包含的目录中。

请注意,在某些版本的 Windows 中,此过程因 SxS 注意事项而变得复杂,您将需要一个清单。您可以自己查找 SxS 和相关问题。