最新公告:

中华视窗是诚信为本,市场在变,我们的诚信永远不变...

中华视窗

咨询热线

400-123-4657

公司动态

当前位置: 首页 > 新闻动态 > 公司动态

动态链接库(dll)与静态连接库(lib)

添加时间:2024-01-27

/

一、前言

dll()动态链接库,包含多个程序执行的代码和数据,程序运行时是需要使用dll;lib()静态链接库,包含dll中各函数的入口信息,在程序编译时用到;动态连接库可以使设计者隐藏函数的具体实现,便于增加代码的复用性;动态链接库参与的程序中,lib文件和dll文件都要用到。

二、dll的生成

头文件中增加下面几行代码

#pragma once
#ifdef XXXX_EXPORTS                        //如果定义了XXXX_EXPORTS 变量
#define DLL_API __declspec(dllexport)      //那么定义DLL_API为__declspec(dllexport)的别名
#else                                      //若梅定义
#define DLL_API __declspec(dllimport)      //定义DLL_API字段为导入
#endif

()为导出标志;若要将某个类导出:

class DLL_API 类名

若要将某个函数导出:

extern "C" 返回值类型 DLL_API 函数名(参数1,参数2,...)

"C"表示在其他类中已经定义了该代码里内容,这里只是声明,“C”表明按照C语言方式进行编译和链接,因为C++编译时会对函数名进行修饰,用于实现函数的重载,而C里面没有这个功能,多以需要用 “C”在而文件头声明时加以区分,以便链接时进行正确的函数名查找;

三、dll和lib的引用

属性—>输入—>附加依赖项,出入需要的XXX.lib文件;将lib文件放到目标工程目录下,确保该目录是在属性—>c++—>常规—>附加包含目录中,若没有,添加即可;将dll文件放到Debug/文件下;在工程文件中太你家与lib名称相同的头文件,文件最上方添加:

class __declspec(dllimport) XXX.lib

公司动态前言_前言动态公司怎么写_公司动态一般都写什么

若导入函数:

extern "C" __declspec(dllimport) void 函数名(参数列表);

导入动态连接库可以也可以如下写法:

#include "../DLL/DLL.h"   //通过相对路径或绝对路径添加头文件
#pragma comment (lib,"../DLL/DLL1.lib")  //添加库文件

四、实例

.h

#pragma once
#include 
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif
 
class DLL_API ExportInterface
{
public:
	virtual void foo() = 0;
	virtual ~ExportInterface()
	{
		std::cout << "call ~ExportInterface"<< std::endl;
	}
};
 
extern "C" DLL_API ExportInterface* getInstance();
extern "C" DLL_API void releaseInstance(ExportInterface* pInstance);
 
#ifdef DLL_EXPORTS  //我们并不需要向外导出该类的定义,在外部代码编译时,也不需要包含此类的定义。
class ExportClass : public ExportInterface
{
private:
	std::string x; //由于外部代码对此不可见,此处的std::string是安全的。
public:
	void foo(); //函数体在dllExample.cpp中实现
	virtual ~ExportClass()
	{
		std::cout << "call ~ExportClass" << std::endl;
	}
};
#endif

.cpp:

#define DLL_EXPORTS
#include "dlltest.h"
#include 
 
extern "C" DLL_API ExportInterface* getInstance()
{
	ExportInterface* pInstance = new ExportClass();
	return pInstance;
}
 
extern "C" DLL_API void releaseInstance(ExportInterface* pInstance)
{
	pInstance->~ExportInterface();
}
 
void ExportClass::foo()
{
	std::cout << "call func foo" << std::endl;
	//do something...
	return;
}

调用

#include 
#include 
#include "dlltest.h"
using namespace std;
// 动态加载DLL
// 函数指针,用于获取GetProcAddress返回的函数地址,并调用DLL中的函数
typedef ExportInterface* (*DllGetInstance)(void);
typedef void (*DllReleaseInstance)(ExportInterface*);
 
int main()
{
	DllGetInstance getInstance;
	DllReleaseInstance releaseInstance;
	ExportInterface* pTest;
	// 显式加载
	HINSTANCE hInstLibrary = LoadLibrary("./TestDll.dll");
 
	if (hInstLibrary == NULL)
	{
		FreeLibrary(hInstLibrary);
		cout << "cant load dll" << endl;
	}
	getInstance = (DllGetInstance)GetProcAddress(hInstLibrary, "getInstance");
	releaseInstance = (DllReleaseInstance)GetProcAddress(hInstLibrary, "releaseInstance");
	if (getInstance == NULL || releaseInstance == NULL)
	{
		FreeLibrary(hInstLibrary);
		cout << "cant get func" << endl;
	}
	
	pTest = getInstance();
	pTest->foo();
	releaseInstance(pTest);
 
	std::cin.get();
 
	FreeLibrary(hInstLibrary);
 
	std::cin.get();
	return 0;
}

具体参考:

C++通过动态链接库导出类,以及的静态链接库LIB和动态链接库DLL基本区别和使用的博客-CSDN博客_c++ dll 导出类

C++动态链接库(dll)与静态链接库(lib)的生成与导入的博客-CSDN博客

联系我们

电话:400-123-4657

传真:+86-123-4567

地址:浙江 温州市 温州大道欧江大厦26188号

邮箱:admin@yina37.com

电话:400-123-4657 传真:+86-123-4567 地址:浙江 温州市 温州大道欧江大厦26188号
版权所有:Copyright © 2002-2024 中华视窗 版权所有 非商用版本 ICP备案编号:粤IP**********    网站地图