添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

dll显示调用(不需要加载头文件和lib库)

2 年前 · 来自专栏 深度学习之tf和pytorch实践

dll显示调用(不需要头文件和lib库)

以前看公司封装的库都是头文件和extern "C" 封装,调用需要头文件和lib库,这就需要考虑.h 和lib路径,而且我每次更改接口需要重新再调用工程里面修改头文件,很不方便,我只是在windows开发,ubuntu发布而已。

今天才发现windows还有另一种调用方式:显示链接

理论:调用动态DLL有两种方法:一种是隐式链接,一种是显式链接,如果用loadlibrary方式就是显示链接,用.h、.lib、.dll三件套就属于隐式链接。

一:隐式链接:

隐式链接采用静态加载的方式,比较简单,需要.h、.lib、.dll三件套。新建“控制台应用程序”或“空项目”。配置如下:

项目->属性->配置属性->VC++ 目录-> 在“包含目录”里添加头文件xxx.h所在的目录

项目->属性->配置属性->VC++ 目录-> 在“库目录”里添加头文件xxx.lib所在的目录

项目->属性->配置属性->链接器->输入-> 在“附加依赖项”里添加“xxx.lib”(若有多个 lib 则以空格隔开) 。

注:也可以在代码中添加一行设置库的链接,

#pragma comment(lib, "xxx.lib")

隐式链接和vs加载配置opencv很像,不做实例展示。

二:显式链接:

今天发现,可以用函数指针来调用dll。

调用步骤:

1、声明头文件<windows.h>,说明我想用windows32方法来加载和卸载DLL

注:如果使用了opencv,不能使用 using namespace cv,可能和windows.h 里面的命名空间冲突,必须使用cv::。(亲自踩坑)

2、然后用typedef定义一个指针函数类型.typedef void(*fun) //这个指针类型,要和你调用的函数类型和参数保持一致

3、定一个句柄实例,用来取DLL的实例地址。HINSTANCE hdll;

格式为hdll=LoadLibrary(“DLL地址”);你封装的dll路径名称

要配置-属性-常规里面把默认字符集“unicode”改成支持多字符扩展。

4、取的地址要判断,定义一个函数指针,用来获取你要用的函数地址。

然后通过Win32 API 函数GetProcAdress来获取函数的地址,参数是DLL的句柄和你要调用的函数名:比如:FUN=(fun)GetProcAdress(hdll,"My_add");

要判断要函数指针是否为空,如果没取到要求的函数,那么要释放句柄。

6、然后通过函数指针来调用函数。

7、调用结束后,就释放句柄FreeLibrary(hdll);

实例展示:

封装:

#include <string>
extern "C" __declspec(dllexport) int My_add(int a,int b)
	printf("%d\n",a+b);
	return a + b;
extern "C" __declspec(dllexport) int My_sub(int a, int b)
	printf("%d\n", a - b);
	return a - b;
}

调用:

#include <string>
#include "Windows.h"
typedef int(*Dllfun)(int, int);
//using namespace std;
//using namespace cv;
int main()
	Dllfun funName;
	HINSTANCE hdll;
	//put DLL under the release path   
	hdll = LoadLibrary(("ThreadLocal.dll"));
	if (hdll == NULL)
		FreeLibrary(hdll);
	funName = (Dllfun)GetProcAddress(hdll, "My_add");//My_sub
	if (funName == NULL)
		FreeLibrary(hdll);
	int x = 1, y = 10;
	int z = funName(x, y);
	printf("z= %d\n", z);
	FreeLibrary(hdll);