C++呼叫動態連結庫DLL的隱式連結和顯式連結基本方法小結
阿新 • • 發佈:2021-09-27
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動態連結庫就可以實現,而隱式連結則稍麻煩(靜態庫和對應動態庫都需要),但如果大量使用連結庫中的函式、類,就有它的優勢。其中的細節很多,另開篇幅再談,感謝閱讀!