C++动态加载dll与extern "C"解析

动态加载dll

相比静态加载dll,动态加载可以在需要使用到dll中的接口时再加载dll,这样的做法不但使得程序更加灵活,而且还可以减轻程序负担。
创建dll,我在这里就不在啰嗦了,直接上代码。

供外部代用的接口 “make_dll.h”

extern "C" __declspec(dllexport) int function_add(int a, int b);

接口实现的代码 “make_dll.cpp”

#include "make_dll.h"
int function_add(int a, int b)
{
	int sum = a + b;
	return sum;
}

直接生成dll文件,将dll文件拷贝到需要使用的项目的执行目录下,进行接下来的代码编写

#include <iostream>
#include <Windows.h>
typedef int (*make_dll)(int,int);//定义指向导出函数的指针类型
int main(){
	HINSTANCE hDLL = LoadLibrary(L"Dll01.dll");
	if (hDLL == nullptr) {
		std::cout << "load dll fail \n";
		return -1;
	}
	make_dll add = (make_dll)GetProcAddress(hDLL, "function_add");
	if (add == nullptr) {
		std::cout << "load address fail \n";
		return -1;
	}
	std::cout << add(10, 20)<< std::endl;
	FreeLibrary(hDLL);//卸载所加载的dll
	system("pause");
	return 0;
}

到这里就已经完成了,执行程序可以看结果
在这里插入图片描述

extern "C"解析

其实在前面的动态加载中遇到一个坑所以才有这里写一下,防止自己以后忘记,大大们可以略过,如果有什么说错的地方还请指正。

首先说一下我遇到的问题:在编写make_dll.h文件时,没有将extern "C"加上,写成了下面的样子

__declspec(dllexport) int function_add(int a, int b);

然后在项目中调用时,一直打印 “load address fail” ,然而用静态加载,就是直接用#pragma comment(lib,“Dll01.lib”),通过头文件调用function_add函数却是可以运行。于是我这个渣渣就只能上网救助了。

以下是我根据网上资料,自己自己总结的,有什么不对的还请指正。

extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C++的。由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;而C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般只包括函数名。

例如函数void add(int, int),编译后的可能是(不同编译器结果不同)_add_int_int(不同编译器可能不同,但都采用了类似的机制,用函数名和参数类型来命名编译后的函数名);而C语言没有类似的重载机制,一般是利用函数名来指明编译后的函数名的。对应上面的函数可能会是_add这样的名字。

参考

c++中的 extern “C”
extern “C"作用
动态库导出声明 : extern “C” __declspec(dllexport) 与 __declspec(dllexport)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章