欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

VisualStudio?制作Dynamic?Link?Library動(dòng)態(tài)鏈接庫(kù)文件的詳細(xì)過(guò)程

 更新時(shí)間:2022年08月01日 08:39:33   作者:CDamogu  
這篇文章主要介紹了VisualStudio?制作Dynamic?Link?Library動(dòng)態(tài)鏈接庫(kù)文件的詳細(xì)過(guò)程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

工具集

借助工具可以獲得Dll庫(kù)函數(shù)的訪(fǎng)問(wèn)地址,以下推薦兩款工具以供使用:

Dependency Walker官網(wǎng)

Depends22_x64.zip

Dllexp-x64.zip

如何生成

__declspec(dllexport)

將一個(gè)函數(shù)聲名為導(dǎo)出函數(shù),就是說(shuō)這個(gè)函數(shù)要被其他程序調(diào)用,即作為DLL的一個(gè)對(duì)外函數(shù)接口。

__declspec(dllexport) RETURN_TYPE FUNCTION()

extern “C”

由于在制作DLL導(dǎo)出函數(shù)時(shí)由于C++存在函數(shù)重載

  • 因此__declspec(dllexport) FUNCTION(int,int)在DLL會(huì)被decorate,例如: 被decorate成為function_int_int,
  • 而且不同的編譯器decorate的方法不同,造成了在用GetProcAddress取得FUNCTION地址時(shí)的不便
  • 使用extern "C"時(shí),上述的decorate不會(huì)發(fā)生,因?yàn)镃沒(méi)有函數(shù)重載,如此一來(lái)被extern"C"修飾的函數(shù),就不具備重載能力
extern "C" {
  __declspec(dllexport) RETURN_TYPE FUNCTION(){
    ;
  }
}

如何使用

  • 動(dòng)態(tài)載入方式是指在編譯之前并不知道將會(huì)調(diào)用哪些 DLL 函數(shù), 完全是在運(yùn)行過(guò)程中根據(jù)需要決定應(yīng)調(diào)用哪些函數(shù)。
  • 方法是:用 LoadLibrary 函數(shù)加載動(dòng)態(tài)鏈接庫(kù)到內(nèi)存,用 GetProcAddress函數(shù)動(dòng)態(tài)獲得 DLL 函數(shù)的入口地址。
  • 當(dāng)一個(gè) DLL 文件用 LoadLibrary 顯式加載后,在任何時(shí)刻均可以通過(guò)調(diào)用 FreeLibrary 函數(shù)顯式地從內(nèi)存中把它給卸載。
  • 動(dòng)態(tài)調(diào)用使用的 Windows API 函數(shù)主要有 3 個(gè), 分別是 LoadLibrary、 GetProcAddressFreeLibrary

聲明調(diào)用

注意DLL函數(shù)調(diào)用約定,必須一致

  • __stdcall Windows API默認(rèn)的函數(shù)調(diào)用協(xié)議
  • __cdecl C/C++默認(rèn)的函數(shù)調(diào)用協(xié)議
  • __fastcall 適用于對(duì)性能要求較高的場(chǎng)合

Example

假如我有一個(gè)函數(shù)接口如下:

//@ GETCOMCHECKSUM_API是一個(gè)宏定義
//@ #define GETCOMCHECKSUM_API __declspec(dllexport)
GETCOMCHECKSUM_API int fnGetComCheckSum(
                        const unsigned char*  iCsArray,       //[In]數(shù)組
                        const unsigned int    iCsSize,        //[In]數(shù)值
                        unsigned char&        ioCsValue)      //[In/Out]數(shù)值

那么我的調(diào)用應(yīng)該這么寫(xiě):

//@ __cdecl * 后面函數(shù)名可以自定義
typedef int(__cdecl *GetComCheckSum)(
            unsigned char const *,
            unsigned int,
            unsigned char&);

LoadLibrary

  • [格式] function LoadLibrary(LibFileName : PChar): Thandle;
  • [功能] 加載由參數(shù) LibFileName 指定的 DLL 文件
  • [說(shuō)明] 參數(shù) LibFileName 指定了要裝載的 DLL 文件名

如果 LibFileName 沒(méi)有包含一個(gè)路徑,系統(tǒng)將按照:當(dāng)前目錄、Windows 目錄、Windows 系統(tǒng)目錄、包含當(dāng)前任務(wù)可執(zhí)行文件的目錄、列在 PATH 環(huán)境變量中的目錄等順序查找文件。

如果函數(shù)操作成功,將返回裝載 DLL 庫(kù)模塊的實(shí)例句柄,否則,將返回一個(gè)錯(cuò)誤代碼,錯(cuò)誤代碼的定義如下表所示

錯(cuò)誤代碼             含義
      0             系統(tǒng)內(nèi)存不夠,可執(zhí)行文件被破壞或調(diào)用非法
      2             文件沒(méi)有被發(fā)現(xiàn)
      3             路徑?jīng)]有被發(fā)現(xiàn)
      5             企圖動(dòng)態(tài)鏈接一個(gè)任務(wù)錯(cuò)誤或者有一個(gè)共享或網(wǎng)絡(luò)保護(hù)錯(cuò)誤
      6             庫(kù)需要為每個(gè)任務(wù)建立分離的數(shù)據(jù)段  
      8             沒(méi)有足夠的內(nèi)存啟動(dòng)應(yīng)用程序  
      10            Windows  版本不正確  
      11            可執(zhí)行文件非法或不是Windows  應(yīng)用程序,或在.  EXE映像中有錯(cuò)誤  
      12            應(yīng)用程序?yàn)橐粋€(gè)不同的操作系統(tǒng)設(shè)計(jì)(如  OS/2)  
      13            應(yīng)用程序?yàn)? MS  DOS   4. 0  設(shè)計(jì)  
      14            可執(zhí)行文件的類(lèi)型不知道  
      15            試圖裝載一個(gè)實(shí)模式應(yīng)用程序(為早期Windows  版本設(shè)計(jì))
      16            試圖裝載包含可寫(xiě)的多個(gè)數(shù)據(jù)段的可執(zhí)行文件的第二個(gè)實(shí)例  
      19            試圖裝載一個(gè)壓縮的可執(zhí)行文件(文件必須被解壓后才能被裝載)  
      20            DLL  文件非法
      21            應(yīng)用程序需要  32  位擴(kuò)展

Example

//@ 定義句柄
HINSTANCE hSnKLib;

//@ 獲取鏈接庫(kù)句柄       Getchecksum為dll的文件名 即 Getchecksum.dll
//@ 系統(tǒng)將會(huì)在當(dāng)前目錄下尋找名為Getchecksum.dll的文件
//@ 至于為什么使用_T("") ,_T是一個(gè)宏,作用是讓你的程序支持Unicode編碼,Windows使用兩種字符集ANSI和UNICODE
hSnKLib = LoadLibrary(_T("Getchecksum"))

//@ 如果未能成功獲取,拋出錯(cuò)誤
if (hSnKLib == NULL)
{
    FreeLibrary(hSnKLib);
  	printf("LoadLibrary err\n");
  	getchar();
  	return 1;
}

GetProcAddress

  • 格式:function GetProcAddress(Module:Thandle; ProcName:PChar): TfarProc;
  • 功能: 返回參數(shù) Module 指定的模塊中,由參數(shù) ProcName 指定的過(guò)程或函數(shù)的入口地址
  • 說(shuō)明: 參數(shù) Module 包含被調(diào)用函數(shù)的 DLL 句柄,這個(gè)值由 LoadLibrary 返回,procName是指向含有函數(shù)名的以 nil 結(jié)尾的字符串指針,或者可以是函數(shù)的次序值.

大多數(shù)情況下,用函數(shù)名是一種更穩(wěn)妥的選擇。

如果該函數(shù)執(zhí)行成功,則返回 DLL 中由參數(shù) ProcName 指定的過(guò)程或函數(shù)的入口地址,否則返回 nil 。

Example

//前面我們?cè)陬^文件中聲明了下述函數(shù)
typedef int(__cdecl *GetComCheckSum)(
            unsigned char const *,
            unsigned int,
            unsigned char&);


//實(shí)例化并且獲取函數(shù)地址
//fnGetComCheckSum為dll export出來(lái)的函數(shù)名,GetComCheckSum為我們引用時(shí)候聲明的函數(shù)名
//這里做的工作就是將dll中函數(shù)與我們聲明的聯(lián)系到一塊。
GetComCheckSum getcom = (GetComCheckSum)GetProcAddress(hSnKLib, "fnGetComCheckSum")

if (!getcom)
{
	FreeLibrary(hSnKLib);			//釋放dll文件
	//Add your code here
}

FreeLibrary

  • 格式:procedure FreeLibrary(Module: Thandle);
  • 說(shuō)明:將由參數(shù) Module 指定的 DLL 文件從內(nèi)存中卸載 1 次。
  • 說(shuō)明:Module 為 DLL 庫(kù)的句柄。這個(gè)值由 LoadLibrary 返回。由于 DLL 在內(nèi)存中只裝載一次,因此調(diào)用 FreeLibrary 首先使 DLL 的引用計(jì)數(shù)減 1,如果計(jì)數(shù)減為 0 則卸載該 DLL
  • 注意:每調(diào)用一次 LoadLibrary 函數(shù)就應(yīng)調(diào)用一次 FreeLibrary 函數(shù),以保證不會(huì)有多余的庫(kù)模塊在應(yīng)用程序結(jié)束后仍留在內(nèi)存中,否則導(dǎo)致內(nèi)存泄漏。

Example

FreeLibrary(hSnKLib);

FAQS

Question 1: GetLastError獲取錯(cuò)誤代碼127

問(wèn)題描述:

  • 采用"運(yùn)行期間動(dòng)態(tài)鏈接"自己的dll文件
  • LoadLibrary成功獲取dll模塊句柄
  • 但是GetProcAddress(hModule, “ExportFunc”)卻返回NULL,GetLastError獲取錯(cuò)誤代碼127,意思是“找不到指定程序”

問(wèn)題定位:

  • 用Depends工具(VS2010默認(rèn)沒(méi)有,需另行下載:http://www.dependencywalker.com/),查看dll的導(dǎo)出函數(shù)名稱(chēng)。
  • 發(fā)現(xiàn)導(dǎo)出函數(shù)名不再是“ExportFunc”,而根據(jù)函數(shù)的返回類(lèi)型和參數(shù)進(jìn)行了“decorate”,變?yōu)榱?ldquo;?ExportFunc@@YAXPB_W@Z”。

解決方法兩種:

  • 修改GetProcAddress的第二個(gè)參數(shù)為真正的導(dǎo)出函數(shù)名稱(chēng)即可
  • 在dll工程中添加DEF文件,寫(xiě)入如下內(nèi)容:
EXPORTS
               ExportFunc
  • 重新編譯dll工程。再次用Depends工具查看導(dǎo)出函數(shù)名稱(chēng),即為“ExportFunc”。
  • 工程–鏈接器–輸入 的模塊定義文件中,將自己的DEF文件加上

在這里插入圖片描述

參考案例

GetProcAddress 使用注意事項(xiàng)

到此這篇關(guān)于VisualStudio 制作Dynamic Link Library動(dòng)態(tài)鏈接庫(kù)文件的文章就介紹到這了,更多相關(guān)VisualStudio動(dòng)態(tài)鏈接庫(kù)文件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++中傳值、傳地址和傳引用究竟有哪些區(qū)別

    C++中傳值、傳地址和傳引用究竟有哪些區(qū)別

    指針是一個(gè)變量,只不過(guò)這個(gè)變量存儲(chǔ)的是一個(gè)地址,指向內(nèi)存的一個(gè)存儲(chǔ)單元,而引用跟原來(lái)的變量實(shí)質(zhì)上是同一個(gè)東西,只不過(guò)是原變量的一個(gè)別名而已,這篇文章主要給大家介紹了關(guān)于C++中傳值、傳地址和傳引用究竟有哪些區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • 詳解c++種gmock單元測(cè)試框架

    詳解c++種gmock單元測(cè)試框架

    這篇文章我們給大家分享了關(guān)于c++種gmock單元測(cè)試框架的相關(guān)知識(shí)點(diǎn)內(nèi)容,有興趣的朋友們學(xué)習(xí)下。
    2018-08-08
  • VC++實(shí)現(xiàn)文件與應(yīng)用程序關(guān)聯(lián)的方法(注冊(cè)表修改)

    VC++實(shí)現(xiàn)文件與應(yīng)用程序關(guān)聯(lián)的方法(注冊(cè)表修改)

    這篇文章主要介紹了VC++實(shí)現(xiàn)文件與應(yīng)用程序關(guān)聯(lián)的方法,涉及VC++針對(duì)注冊(cè)表的相關(guān)操作技巧,需要的朋友可以參考下
    2016-08-08
  • Visual?Studio2022下Opencv的配置圖文教程

    Visual?Studio2022下Opencv的配置圖文教程

    本文主要介紹了Visual?Studio2022下Opencv的配置圖文教程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • C語(yǔ)言在linux下編程詳解

    C語(yǔ)言在linux下編程詳解

    這篇文章主要介紹了linux下基于C語(yǔ)言的編程,實(shí)例分析了基本使用技巧與相關(guān)概念,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • C/C++的內(nèi)存管理你了解嘛

    C/C++的內(nèi)存管理你了解嘛

    這篇文章主要為大家介紹了C/C++的內(nèi)存管理,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助
    2022-01-01
  • Typedef在C語(yǔ)言和C++中的用法和區(qū)別

    Typedef在C語(yǔ)言和C++中的用法和區(qū)別

    在C語(yǔ)言和C++中,typedef是一個(gè)非常常用的關(guān)鍵字,用于為數(shù)據(jù)類(lèi)型定義別名,盡管它在兩種語(yǔ)言中都有相似的功能,但由于C++具有更豐富的類(lèi)型系統(tǒng),因此在實(shí)際應(yīng)用中,typedef在兩者間的使用存在一些微妙的差異
    2024-01-01
  • 淺談返回函數(shù)內(nèi)部new分配的內(nèi)存的引用

    淺談返回函數(shù)內(nèi)部new分配的內(nèi)存的引用

    下面小編就為大家?guī)?lái)一篇淺談返回函數(shù)內(nèi)部new分配的內(nèi)存的引用。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-12-12
  • C++實(shí)現(xiàn)簡(jiǎn)單走迷宮的代碼

    C++實(shí)現(xiàn)簡(jiǎn)單走迷宮的代碼

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)單走迷宮的代碼,利用回溯法求解,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-05-05
  • OpenCV實(shí)現(xiàn)拼圖板小游戲

    OpenCV實(shí)現(xiàn)拼圖板小游戲

    這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)拼圖板小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-05-05

最新評(píng)論