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)

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