visual-c++ - .h、.dll 和 .lib 混淆

标签 visual-c++

我是 vc++ 的新手。我刚刚构建了一个软件,它生成了一个 .dll 和一个 .lib。我需要在我的代码中使用这个函数。我需要链接到 .lib 和 .dll 来构建我的代码吗?我必须更改哪些项目属性才能进行此链接?

最佳答案

实际上,您只需要 .dll 文件。它包含运行其功能所需的所有代码和数据。它还包含一个表,该表链接了函数的符号名称(例如函数 PrintMe)、它们的序号(DLL 中该函数的编号)以及它们在 DLL 中的地址。
如果您只想使用 DLL,则必须“手动”解析符号:
假设您要使用 DLL 的函数 PrintMe。您需要做的是将它的名称 (PrintMe) 或它的序号(PrintMe 是 DLL 的第一个函数)解析为它的地址。为此,您可以使用 Win32 API(又名 Windows SDK)中的 LoadLibrary、GetModuleHandle 和 GetProcAdress。此外,此方法允许您在运行时加载 DLL(见下文)。

更简单的方法是使用 MSVC(++) 功能 __declspec(dllexport) 和 __declspec(dllimport),例如


// your DLL
__declspec(dllexport) void PrintMe()
{
    printf("Hello World!");
}

// you project to use the DLL
__declspec(dllimport) void PrintMe();

第一个(dllexport)告诉编译器导出函数。第二个(dllimport)很有趣:它创建了所有必要的代码,以便能够使用 DLL 中的函数。
为此,您需要项目中的 .lib 文件(要使用 DLL)。 .lib 文件包含链接器将符号名称 (PrintMe) 解析为其在 DLL 中的地址的信息。由于 .lib 是静态绑定(bind)的,因此链接器可以使用它 - 相反,DLL 在运行时/加载时绑定(bind),因此链接器无法使用它。 (是的,.lib 文件中的信息是多余的。)。注意:使用此方法时,您无法更改整个 DLL,而无需使用新的 .lib 文件重新构建项目。某些结构更改会影响 DLL 中函数的地址,请参阅 this SO answer .
使用 Win32 API (LoadLibrary...) 和通过 __declspec 的 MSVC 方法之间的最后一个区别是 DLL 的加载。当您使用 LoadLibrary 时,DLL 是在运行时加载的,当然(因此您可以在找不到异常时捕获异常等等)。另一种方法在加载时加载 DLL,因此当 Windows 找不到 DLL 时,您的程序将终止(不会运行)。

在 VS 中创建项目时,可以在向导(Win32 项目)末尾激活“导出符号”复选框。这为您提供了一些导出符号的示例。此外,它还引入了一个宏、一个预处理器定义以及一些非常有用的指令:

// DLL header

#ifdef _YOUR_DLL_EXPORTS
#define YOUR_DLL_API __declspec(dllexport)
#else
#define YOUR_DLL_API __declspec(dllimport)
#endif

YOUR_DLL_API PrintMe();

您现在可以使用此头文件来构建您的 DLL,因为您的 DLL 项目具有该 _YOUR_DLL_EXPORTS 定义(请参阅项目属性页、C++、预处理器)。使用 DLL 的项目也可以使用这个头文件,但不能定义这样的名称。当您在要在其中使用 DLL 的项目中包含头文件时,宏将解析为 __declspec(dllimport)。这指示链接器查找此函数(在 .lib 文件中找到)并创建所有必要的代码以在运行时加载 DLL 并解析符号名称。

关于visual-c++ - .h、.dll 和 .lib 混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3598980/

相关文章:

c++ - Intellisense 突然停止工作或在 VS2008 中显示很多不一致

c++ - 可以在 C++ 中的字符串文字中写入 unicode 字符吗

visual-c++ - 如何在 asm *without* label 中实现条件跳转?

c++ - 如何编写支持 LTO 的代码?

visual-c++ - vc++安装创建者

windows - struct sockaddr,sin_family不是成员

visual-c++ - CUDA - 数组在 GPU 上生成随机数组及其使用内核的修改

c++ - 映射问题

visual-c++ - VC++ Express Edition 中缺少 afxwin.h 文件

c++ - 在 VC++ 中编译头文件时遇到问题