c++ 动态加载DLL和静态加载DLL以及DLL的编写

1、DLL的编写

新建win32控制台或者win32项目,然后选择DLL

下面是自动生成的文件MyDll.h

// 下列 ifdef 块是创建使从 DLL 导出更简单的
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 MYDLL_EXPORTS
// 符号编译的。在使用此 DLL 的
// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// MYDLL_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif

// 此类是从 MyDll.dll 导出的
class MYDLL_API CMyDll {
public:
	CMyDll(void);
	// TODO:  在此添加您的方法。
public:
	int MyPrint();
};

extern MYDLL_API int nMyDll;

MYDLL_API int fnMyDll(void);

MyDll.cpp

// MyDll.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"
#include "MyDll.h"
#include <stdio.h>

// 这是导出变量的一个示例
MYDLL_API int nMyDll=0;

// 这是导出函数的一个示例。
MYDLL_API int fnMyDll(void)
{
    return 42;
}

// 这是已导出类的构造函数。
// 有关类定义的信息,请参阅 MyDll.h
CMyDll::CMyDll()
{
    return;
}

int CMyDll::MyPrint()
{
	printf("我是DLL中的函数");
	return 100;
}

这其中的MyPrint函数是我自己添加的。

然后编译。

2、静态加载DLL

        静态加载需要.h和.lib以及.dll文件。

接来下调用静态加载:

新建一个项目,然后把这三个文件拷贝进来

 

当然静态调用DLL,很简单。而且还算方便。但是当你知道动态调用DLL的时候,你就会发现动态调用DLL更灵活,强大。

3、动态加载DLL

        就是说,你不需要.h和.lib文件,只需要.dll文件,同时知道你所要使用的函数的参数类型以及返回值类型。

我还是拿刚刚那个DLL为例。不过要稍微改变一下。

这个时候我在原来的MyDll项目中改变了如下文件

MyDll.def

LIBRARY    "MyDll"
EXPORTS
    getInstance

MyDll.h

// 下列 ifdef 块是创建使从 DLL 导出更简单的
// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 MYDLL_EXPORTS
// 符号编译的。在使用此 DLL 的
// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将
// MYDLL_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的
// 符号视为是被导出的。
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif


class CDLL
{
public:
	virtual int MyPrint() = 0;

};


// 此类是从 MyDll.dll 导出的
class  CMyDll :public CDLL {
public:
	CMyDll(void);
	// TODO:  在此添加您的方法。
public:
	int MyPrint();
};

CDLL * getInstance();

MyDll.cpp

// MyDll.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"
#include "MyDll.h"
#include <stdio.h>


// 这是已导出类的构造函数。
// 有关类定义的信息,请参阅 MyDll.h
CMyDll::CMyDll()
{
    return;
}

int CMyDll::MyPrint()
{
	printf("我是DLL中的函数");
	return 100;
}

CDLL * getInstance()
{
	return new CMyDll();
}

我新建了一个虚基类,然后让MyDll继承,这样我就能使用多态,然后类的实例,然后操作了。

再新建一个调用动态DLL的项目,然后把这个MyDll.dll拷贝过来

源.cpp

#include <iostream>
#include <windows.h>
using namespace std;

class CDLL
{
public:
	virtual int MyPrint() = 0;

};


int main()
{
	HINSTANCE hDll;//句柄

	typedef CDLL*(*MyGetInstance)();
	MyGetInstance instance;//函数指针
	hDll = ::LoadLibrary(L"MyDll.dll");//动态加载DLL模块句柄
	if (hDll)
	{
		instance = (MyGetInstance)GetProcAddress(hDll, "getInstance");//得到所加载DLL模块中函数的地址
		
		CDLL *dll = instance();
		int ret = dll->MyPrint();
		cout << "ret=" << ret << endl;
		FreeLibrary(hDll);//释放已经加载的DLL模块
	}

	system("pause");
	return 0;
}

输出结果如下

最后,我再把整个源代码放出来,你们下载可以研究一下。我最讨厌放源代码还放在CSDN上面。让那些没有积分的人很难受,所以我的任何东西需要下载的都不放CSDN上,百度云链接:

链接:https://pan.baidu.com/s/1O9uNwZ5WcTDFiojkYTdMQA 
提取码:yu23 

 

欢迎关注我们的公众号,本人知识能力有限,如果文章中有错误的地方欢迎向我反馈或者留言,十分感谢!

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值