MFC:动态链接库

本文详细介绍了如何在MFC环境下创建和使用动态链接库(DLL),包括导出函数、头文件声明、宏定义、类导出、C调用约定以及动态加载DLL的方法。示例涵盖了从简单的函数导出到处理名称修饰问题,提供了实用的编程技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<span style="font-size:18px;"><span style="font-size:18px;"></span>
<span style="font-size:18px;">
</span>
<span style="font-size:18px;">文件/新建 Win32 Dynamic-Link Library;文件/新建 C++ SourceFile:
_declspec(dllexport) int add(int a,int b){
	return a+b;
}
_declspec(dllexport)int subtract(int a,int b){
	return a-b;
}
测试文件调用动态链接库中函数的声明:
//_declspec(dllimport) int add(int a,int b);
//_declspec(dllimport) int subtract(int a,int b);
/***********************************************************************************/
通常会给动态链接库提供一个头文件(包含了要导出的函数原型的声明,注释文档):
_declspec(dllimport) int add(int a,int b);
_declspec(dllimport) int subtract(int a,int b);
让调用动态链接库函数的程序添加此头文件。
/***********************************************************************************/
使动态链接库既可给应用程序使用,又可供动态链接库自身使用:
在 .h 头文件中:
#ifdef DLL1_API
#else
#define DLL1_API _declspec(dllimport)
#endif
DLL1_API  int add(int a,int b);
DLL1_API  int subtract(int a,int b);
在 .cpp 源文件中:
#define DLL1_API __declspec(dllexport)  //在动态链接库中定义宏的作用是导出函数
#include "*.h"
int add(int a,int b){
	return a+b;
}
int subtract(int a,int b){
	return a-b;
}
//在应用程序中不定义宏,就表示导入函数
动态链接库中导出类,在class 后加上宏,类的成员函数都会被导出;
要导出类中的函数,函数定义前加上宏,此时虽然没导出类,但仍可声明类,然后调用导出的函数(public).
/***********************************************************************************/
C++编译器会进行名字改变,若用C编译器就可能导致访问失败:
在定义宏的后面加上 extern "C" // C 必须是大写
#define DLL1_API extern "C" _declspec(dllimport)
// extern "C" 不能导出类的成员函数,只能导出全局函数,不让其发生名字改变
DLL1_API  int _stdcall add(int a,int b);
DLL1_API  int _stdcall subtract(int a,int b); //标准调用约定,没有_stdcall的是 C调用约定
int _stdcall add(int a,int b){
	return a+b;
}
int _stdcall subtract(int a,int b){
	return a-b;
}  
//若动态链接库给C使用,extern "C";若给C++使用,_stdcall,但这样会使函数名发生改变,cry!
/////////////////////////////////////nothing///////////////////////////////////
可以使用模块定义文件(.def)来解决名字改变问题(laughter):
将def文件添加到动态链接库工程文件中。
.def:
LIBRARY Dll2
EXPORTS
add		//链接器发现此名和源文件中函数名相同,就会用add来导出add函数
subtract
源文件只需如此这般:
int add(int a,int b){
	return a+b;
}
int subtract(int a,int b){
	return a-b;
}
/***********************************************************************************/
动态加载动态链接库(前面都是隐式加载,在链接器选项中输入.lib):
LoadLibrary()
GetProcAdress()
void CDllTestDlg::OnBtnAdd(){
	HINSTANCE hInst;
	hInst=LoadLibrary("Dll3.dll"); //得到动态链接库模块的句柄
	typedef int (/*_stdcall*/ *ADDPROC)(int a,int b); //定义一个函数指针类型
	//ADDPROC Add=(ADDPROC)GetProcAddress(hInst,"?add@@YAHHH@Z"); //会发生名字改编
	ADDPROC Add=(ADDPROC)GetProcAddress(hInst,MAKEINTRESOURCE(1));//通过函数序号访问(可能出错)
	if(!Add){	
		MessageBox("获取函数地址失败!");
		return;
	}
	CString str;
	str.Format("5+3=%d",Add(5,3));
	MessageBox(str);
	FreeLibrary(hInst); //减少加载的动态链接库的引用计数
}// 动态加载不需头文件,不需lib文件,只需dll即可(把dll文件复制到工程文件中)
当需要访问好多动态链接库时,或只需动态链接库中的少数函数(若隐式把整个动态链接库加载到内存,资源浪费)
适合用动态链接。</span>
<span style="font-size:18px;">
</span>
<span style="font-size:18px;">
</span></span>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值