中华视窗是诚信为本,市场在变,我们的诚信永远不变...
一、前言
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博客