C++动态调用dll库及回调

 1   动态库与静态库区别

静态库

当程序与静态库连接时,库中目标文件所含的所有将被程序使用的函数的机器码被 copy 到最终的可执行文件中。这就会导致最终生成的可执行代码量相对变多,相当于编译器将代码补充完整了,优点,这样运行起来相对就快些。不过会有个缺点: 占用磁盘和内存空间. 静态库会被添加到和它连接的每个程序中, 而且这些程序运行时, 都会被加载到内存中. 无形中又多消耗了更多的内存空间。

动态库

与共享库连接的可执行文件只包含它需要的函数的引用表,而不是所有的函数代码,只有在程序执行时, 那些需要的函数代码才被拷贝到内存中优点,这样就使可执行文件比较小, 节省磁盘空间,更进一步,操作系统使用虚拟内存,使得一份共享库驻留在内存中被多个程序使用,也同时节约了内存。缺点,不过由于运行时要去链接库会花费一定的时间,执行速度相对会慢一些,总的来说静态库是牺牲了空间效率,换取了时间效率,共享库是牺牲了时间效率换取了空间效率

下面用两个接口分别实现动态库的调用及回调

  1. dll实现加法运行,应用程序调用dll,将加法结果计算出;
  2. dll实现加法运行,应用程序调用dll,将加法结果计算出;并且将计算过程通过回调返回给应用程序(实际应用中是比加法更加复杂,这里只是)

2    创建动态库,dll中定义和实现接口

DllAPI.h

#ifndef __DLLAPI_DEF__
#define __DLLAPI_DEF__

typedef void (CALLBACK* CallBackFun)(bool bRet);

extern "C" int _declspec(dllexport) add(int x, int y);
extern "C" int _declspec(dllexport) addEx(int x, int y, CallBackFun fun);

#endif

DllAPI.cpp

#include "stdafx.h"
#include "DllAPI.h"

int add(int x, int y)
{
	return x + y;
}

int addEx(int x, int y, CallBackFun fun)
{
	int a = x + y;
	//处理流程...

	//处理完成,返回状态传给应用程序
	bool bRet = true;
	fun(bRet);
	return a;
}

 3    创建动态库,dll中定义和实现接口

MyDLL.h

#ifndef __MYDLL_DEF__
#define __MYDLL_DEF__
#include <Windows.h>
#include <atlstr.h>
#include <string>
using namespace std;


//回调定义
typedef void (CALLBACK* CallBackAdd)(bool bRet);

//宏定义函数指针类型
typedef int(*lpAddFun)(int, int); 
typedef int(*lpAddFunEx)(int, int, CallBackAdd);

//函数指针声明
extern lpAddFun addFun;
extern lpAddFunEx addFunEx;

bool LoadCtrl(CString strPath);
void FreeCtrl();

#endif

MyDLL.cpp

#include "stdafx.h"
#include "MyDLL.h"

HINSTANCE g_hCtrlInstance = NULL;

//函数指针
lpAddFun addFun = NULL; 
lpAddFunEx addFunEx = NULL;

bool LoadCtrl(CString strPath)
{
	g_hCtrlInstance = LoadLibrary(strPath);
	if (!g_hCtrlInstance)
	{
		return false;
	}

	addFun = (lpAddFun)GetProcAddress(g_hCtrlInstance, "add");/*用addFun取代dll库中的add函数*/
	addFunEx = (lpAddFunEx)GetProcAddress(g_hCtrlInstance, "addEx");

	return true;
}

void FreeCtrl()
{
	FreeLibrary(g_hCtrlInstance);
}

4    应用程序调用DLL

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

void CALLBACK CallBackAddFunRet(bool bRet)
{
	if (bRet)
	{
		printf("回调成功,bRet=true");
	} 
	else
	{
		printf("回调成功,bRet=false");
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	if (!LoadCtrl(_T("DLL.dll")))
	{
		return -1;
	}

	int nSum = addFun(1, 2);
	int nSumEx = addFunEx(3, 4, CallBackAddFunRet);

	FreeCtrl();

	return 0;
}

5    例子下载

上述代码已经实现并且编译通过,有兴趣可以通过如下链接进行下载

(61条消息) C++,动态调用dll,dll也是由c++实现,且实现了回调功能,即应用程序将函数传入到dll,由dll接口调用函数,以实现回调-C++文档类资源-CSDN文库

6   相应接口参考

Dynamic-Link Library Functions - Win32 apps | Microsoft Docs

The following functions are used in dynamic linking.

Function

Description

AddDllDirectory

Adds a directory to the process DLL search path.

DisableThreadLibraryCalls

Disables thread attach and thread detach notifications for the specified DLL.

DllMain

An optional entry point into a DLL.

FreeLibrary

Decrements the reference count of the loaded DLL. When the reference count reaches zero, the module is unmapped from the address space of the calling process.

FreeLibraryAndExitThread

Decrements the reference count of a loaded DLL by one, and then calls ExitThread to terminate the calling thread.

GetDllDirectory

Retrieves the application-specific portion of the search path used to locate DLLs for the application.

GetModuleFileName

Retrieves the fully qualified path for the file containing the specified module.

GetModuleFileNameEx

Retrieves the fully qualified path for the file containing the specified module.

GetModuleHandle

Retrieves a module handle for the specified module.

GetModuleHandleEx

Retrieves a module handle for the specified module.

GetProcAddress

Retrieves the address of an exported function or variable from the specified DLL.

LoadLibrary

Maps the specified executable module into the address space of the calling process.

LoadLibraryEx

Maps the specified executable module into the address space of the calling process.

LoadPackagedLibrary

Maps the specified packaged module and its dependencies into the address space of the calling process. Only Windows Store apps can call this function.

RemoveDllDirectory

Removes a directory that was added to the process DLL search path by using AddDllDirectory.

SetDefaultDllDirectories

Specifies a default set of directories to search when the calling process loads a DLL.

SetDllDirectory

Modifies the search path used to locate DLLs for the application.

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值