Visual c++ .h、.dll和.lib混淆

Visual c++ .h、.dll和.lib混淆,visual-c++,Visual C++,我是vc++新手。我刚刚构建了一个软件,它生成了一个.dll和一个.lib。我需要在我的代码中使用这个函数。我是否需要链接到.lib和.dll来构建代码?要进行此链接,我必须更改哪些项目属性?实际上,您只需要.dll文件。它包含运行其函数所需的所有代码和数据。它还包含一个表,链接函数的符号名称(例如函数PrintMe)、它们的序号(DLL中该函数的编号)以及它们在DLL中的地址。 如果只想使用DLL,则必须“手动”解析符号: 假设您想使用DLL的函数PrintMe。您需要做的是将它的名称(Pri

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

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

更简单的方法是使用MSVC(++)特性uu declspec(dllexport)和u declspec(dllimport),例如

第一个(dllexport)告诉编译器导出函数。第二个(dllimport)很有趣:它创建所有必要的代码,以便能够使用DLL中的函数。
为此,您需要在项目中使用.lib文件(希望使用DLL)。lib文件包含链接器将符号名(PrintMe)解析为其在DLL中的地址的信息。由于.lib是静态绑定的,链接器可以使用它-相反,DLL是在运行时/加载时绑定的,因此链接器无法使用它。(是的,.lib文件中的信息是多余的。)。注意:使用此方法时,如果不使用新的.lib文件重建项目,则无法更改整个DLL。某些结构更改会影响DLL中函数的地址,请参阅。
使用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项目具有那个您的YouLyDLL导出定义(参见Project Projage Page、C++、Primor)。使用DLL的项目也可以使用此标头,但不得定义此名称。在要使用DLL的项目中包含头文件时,宏将解析为_declspec(dllimport)。这将指示链接器查找此函数(可在.lib文件中找到),并创建所有必要的代码,以便在运行时加载DLL并解析符号名。

另请参见,还应注意,还有一种称为“导入库”的检查@WakanTanka Yes,这就是我在回答中所说的自由。谢谢你的链接。

// DLL header

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

YOUR_DLL_API PrintMe();