如何创建和加载动态链接库DLL

动态链接库DLL的动态加载

DLL,即动态链接库(Dynamic Link Library),在实际应用开发过程中,为了以后对已经开发好的软件程序进行更好的维护和管理,程序的模块化是一个很好的管理方法,程序员大都喜欢把某一模块的功能做成dll文件,然后导入到工程目录中,再进行加载即可调用dll里面的函数,大大的减少了代码的阅读量,节省大量的宝贵时间,如果需要对dll里面的具体方法进行修改,直接打开生成dll文件即可,不需要在整个工程项目中查找,如果工程量较大,那查找其中某一个模块必定是一件费时的事情。那也说明了dll/模块化细想的重要性。

动态链接库的加载方式:

一.动态加载 (显式调用)

二.静态加载(隐式调用)

静态链接库:
   1.lib中的函数不仅被连接,而且全部实现都被直接包含在最终生成的EXE文件中,但是其具体实现是不可见的。
   2.静态调用中,由编译系统完成对DLL的加载和应用程序结束时DLL的卸载:
   释放已经加载的DLL模块: FreeLibrary(hDll);
	3.静态调用:.cpp文件中包含对应的.h文件,并写上如下语句:
	#pragma comment(lib,"xxx.lib") //告诉编译器DLL相对应的lib文件所在路径和文件名
	 extern "C" _declspec(dllimport) int _stdcall Camera();//声明导入函数

动态链接库:
   1.dll不必被包含在最终的EXE中,动态调用时仅把函数名或者变量名或者类名链接到.EXE文件中,而这些东西的实体都只有在运行时才从动态库中导入到可执行
   文件中,动态调用中.EXE文件执行时可以直接动态地引用和卸载DLL文件。
   2.动态调用中,由程序员用API函数加载和卸载DLL
   方式:(DLL加载—DLL函数地址获取—DLL释放)

注意:静态链接库中不能再包含其他的动态链接库或静态库,而动态链接库中可以包含其他的动态或静态库。
导出函数的声明方式:

方式1:在函数声明类型和函数名之间加上“_declspec(dllexport)”。
方式2:采用模块定义(.def)文件声明,需要在库工程中添加模块文件,格式如下:
  LIBRARY 库工程名称
  EXPORTS 导出函数名

同时,DLL导出函数(或变量、类)可供应用程序调用;DLL内部函数只能在DLL程序内使用,应用程序无法调用它们。
  
  一、创建动态链接库(MFC规则DLL)
  其实,DLL的编制与具体的编程语言及编译器无关,VC++支持三种DLL:非MFC动态库、MFC规则DLL、MFC扩展DLL。
  创建步骤:
  1. 新建一个MFC AppWizard(dll),动态链接库使用 共享MFC DLL
  2. def文件中添加:函数名(Camera)
  3. h文件中添加:外部函数声明 ,如:Initialize
  extern “C” __declspec(dllexport) int __stdcall Initialize();
  4. cpp文件中添加: 外部函数实现
  extern “C” __declspec(dllexport) int __stdcall Initialize()
  {
   //函数具体功能
  }

或者用以下例子创建dll

.h文件:


#pragma once
class Camera
{
public:
	virtual BOOL Initialize() = 0;
	virtual void DeleteThis() = 0;
	//xxx
	//xxx
};
//定义一个与Add_new函数接受参数类型和返回值均相同的函数指针类型
typedef Camera* (__stdcall * CREATE_Camera  )();

需要在.cpp文件中对其函数具体实现,这里主要是说明如何应用,如何实现就不写出来了。
  
对于 dll的加载,下面给出1个例子来说明:
首先,假设已经有一个Camera.dll 和Camera.ib文件,把其拷背到项目工程debug目录下,然后在调用处进行加载

根据名字/地址进行动态加载:

步骤:

1.使用LoadLibrary载入动态链接库
2.使用GetProcAddress获取函数地址
	//Dll文件
	CString strDllName = _T("Camera.dll");
	//句柄
	HINSTANCE m_hInstDLL;
	//动态加载DLL模块句柄
	 m_hInstDLL = ::LoadLibrary (strDllName); 
	//函数指针
	CREATE_Camera  pfCreate;
	if (m_hInstDLL == NULL)
	{
		AfxMessageBox(_T("Load library: ")+ strDllName + _T(" fail!"));
	}
	else
	{
	//1.根据地址加载:得到所加载DLL模块中函数的地址
	//CREATE_Camera pfCreate = (CREATE_Camera)::GetProcAddress (m_hInstDLL, "?CreateDVPCamera@@YAPAVCCamera@@XZ"); 
	//2.根据名字加载:
	    pfCreate =(CREATE_Camera)::GetProcAddress(m_hInstDLL,"CreateDVPCamera"); 
		if( !pfCreate )
		{
			AfxMessageBox(_T("Load library: ") + strDllName + _T(",Fail to Get Proc address:")+_T("CreateDVPCamera"));	
			DWORD dErr = GetLastError();
		}
		else
		{
			m_pCamera =  (*pfCreate)();
			m_Camera->Initialize();	
			AfxMessageBox(_T("success ") );	
		}
	}


说明:
  上面例子中,根据地址加载方式中,地址
  “?CreateDVPCamera@@YAPAVCCamera@@XZ”
  要通过Dependency Walker工具打开DLL文件直接进行获得。

结语:感谢大家的浏览!

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

随心漂流

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值