1. 程式人生 > 其它 >C++呼叫動態連結庫DLL的隱式連結和顯式連結基本方法小結

C++呼叫動態連結庫DLL的隱式連結和顯式連結基本方法小結

C++程式在執行時呼叫動態連結庫,實現邏輯擴充套件,有兩種基本連結方式:隱式連結顯式連結。下面就設立最基本情形實現上述連結。


建立DLL動態連結庫

編輯標頭檔案

mydll_3.h:

#pragma once
#define DLL_EXPORT_API extern "C" _declspec(dllexport)  

//Function  
DLL_EXPORT_API int Add(int a, int b);

//Class  
class _declspec(dllexport) Math
{
public:
	int Multiply(int a, int b);
};

stdafx.h:

// stdafx.h : 標準系統包含檔案的包含檔案,
// 或是經常使用但不常更改的
// 特定於專案的包含檔案
//

#pragma once

#include "targetver.h"

#define WIN32_LEAN_AND_MEAN             // 從 Windows 頭中排除極少使用的資料
// Windows 標頭檔案: 
#include <windows.h>

// TODO: 在此處引用程式需要的其他標頭檔案

targetver.h:

#pragma once

// 包括 SDKDDKVer.h 將定義可用的最高版本的 Windows 平臺。

// 如果要為以前的 Windows 平臺生成應用程式,請包括 WinSDKVer.h,並將
// 將 _WIN32_WINNT 巨集設定為要支援的平臺,然後再包括 SDKDDKVer.h。

#include <SDKDDKVer.h>

編輯實現方法

mydll_3.cpp

// mydll_3.cpp: 定義控制檯應用程式的入口點。
//

#include "stdafx.h"

#include "mydll_3.h"  

int Add(int a, int b)
{
	return a + b;
}

int Math::Multiply(int a, int b)
{
	return a * b;
}

stdafx.cpp:

// stdafx.cpp : 只包括標準包含檔案的原始檔
// mydll_3.pch 將作為預編譯標頭
// stdafx.obj 將包含預編譯型別資訊

#include "stdafx.h"

// TODO: 在 STDAFX.H 中引用任何所需的附加標頭檔案,
//而不是在此檔案中引用

檢查配置

配置選擇【動態庫.dll】生成,即可得到對應動態連結庫DLL對應的靜態連結庫LIB。一般的,靜態庫包含函式的入口資訊、類宣告等資訊,動態庫中包含具體實現方法。

建立可執行檔案EXE

接下來建立exe來呼叫連結庫中的資訊。

編輯標頭檔案

stdafx.h:

// stdafx.h : 標準系統包含檔案的包含檔案,
// 或是經常使用但不常更改的
// 特定於專案的包含檔案
//

#pragma once

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>

// TODO: 在此處引用程式需要的其他標頭檔案

targetver.h:

#pragma once

// 包括 SDKDDKVer.h 將定義可用的最高版本的 Windows 平臺。

// 如果要為以前的 Windows 平臺生成應用程式,請包括 WinSDKVer.h,並將
// 將 _WIN32_WINNT 巨集設定為要支援的平臺,然後再包括 SDKDDKVer.h。

#include <SDKDDKVer.h>

編輯實現方法

mytest_3.cpp:

// mytest_3.cpp: 定義控制檯應用程式的入口點。
//

#include "stdafx.h"
#include "mydll_3.h"
#include "windows.h"

#pragma comment(lib,"mydll_3.lib")  //意為告知編譯器需要連結一個庫,名叫 mydll_3.lib
//extern "C"_declspec(dllimport) int Add(int a, int b); //此處可有可無


// !!! 隱式連結 !!!
//TestDll.cpp  
//void main()
//{
//	int a;
//	a = Add(8, 10);
//	printf("結果為%d\n",a);
//	Math m;
//	printf("%d\n",m.Multiply(5, 3));
//	system("pause");
//}


// !!! 顯式連結(動態) !!!
void main(void)
{
	typedef int(*pAdd)(int a, int b);
	HINSTANCE hDLL;
	pAdd Add;
	hDLL = LoadLibrary(_T("mydll_3.dll"));//載入動態連結庫MyDll.dll檔案;  
	Add = (pAdd)GetProcAddress(hDLL, "Add");
	int a = Add(5, 8);
	printf("結果為%d\n",a);
	FreeLibrary(hDLL);//解除安裝myDll.dll檔案;
	system("pause");
}

stdafx.cpp:

// stdafx.cpp : 只包括標準包含檔案的原始檔
// mytest_3.pch 將作為預編譯標頭
// stdafx.obj 將包含預編譯型別資訊

#include "stdafx.h"

// TODO: 在 STDAFX.H 中引用任何所需的附加標頭檔案,
//而不是在此檔案中引用

檢查配置

確保動態庫DLL和對應靜態庫LIB在開發目錄下,配置選擇【應用程式.exe】,生成即可!如果要釋出,將可執行檔案exe和動態連結庫dll一起拷貝至目標資料夾(靜態庫lib不需要隨exe拷貝)。

小結

有些配置如果是用Visual Studio來開發的話能在其選項中具體設定,比較方便,比如專門有【連結器】配置等。顯式連結比較靈活,只需dll動態連結庫就可以實現,而隱式連結則稍麻煩(靜態庫和對應動態庫都需要),但如果大量使用連結庫中的函式、類,就有它的優勢。其中的細節很多,另開篇幅再談,感謝閱讀!