如何使用 dll
How to use a dll
我最近在尝试使用 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"。
- 旁注:Java 和 CLR 等运行时为组件提供了一种类似 COM 的方式来声明它们包含的类和组件,并允许其他程序在运行时引用和使用这些对象,而无需任何编译时链接。Microsoft Windows 8.0(及更高版本(使用"Windows 运行时"将此方法推广到更可执行的二进制类型,其中简单的元数据文件(
若要使用 DLL,请:
- 编译时
#include
头文件。 - 在链接过程中包括
.lib
文件("implib"(,以便链接器知道符号在运行时来自 DLL。 - 安排.dll文件存在于
PATH
环境变量中包含的目录中。
请注意,在某些版本的 Windows 中,此过程因 SxS 注意事项而变得复杂,您将需要一个清单。您可以自己查找 SxS 和相关问题。
- 当我使用 C++ 中的 C# dll 来使用 Selenium 时,存在异常处理问题
- 将 c++ 生成器应用程序与外部 dll 结合使用
- 将 Lua 与 C++ DLL 结合使用
- 在OpenCV_core310.dll中使用findContours函数时,OpenCV引发未处理的异常
- 如何初始化堆,以便静态构造函数可以在常规 MFC dll 中使用堆?
- 我可以在 Win32 DLL 中使用 LoadLibrary 吗?
- 将 std::string 传递给 C++ DLL 以便与 C# dll 一起使用
- 如何在另一个 DLL 上使用 '/DELAYLOAD' 的 DLL
- 在我的 dll 中使用模板类
- 在同一DLL中使用_COM_SMARTPTR CreateInstance而不进行注册
- 在 MFC 扩展 DLL 中使用 BCGControlBar
- 如何在dll中使用CUDA
- 提高.测试 在 dll 中使用 BOOST 测试用例和在 exe 中的运行器中出现问题
- C++ 2 个 DLL 相互使用
- 在DLL中使用类
- 是否有必要注册DLL来使用它
- 在静态LIB和DLL中使用静态成员 - 成员值正在重置
- 在JNI创建的dll中使用dll的问题
- 在DLL中使用的最简单的C++PUSH通知/POST解决方案
- 在Windows CE DLL中使用__stdcall和__cdecl