VS下動態庫dll的顯式呼叫(動態呼叫)
VS下動態庫dll的顯式呼叫
動態庫的載入分兩種形式:分為靜態載入和動態載入。靜態載入時,對應的標頭檔案、DLL,和LIB缺一不可,並且生產的EXE沒有找到DLL檔案就會導致“應用程式初始化失敗”。動態載入只需要dll,通過LoadLibrary()函式進行載入,但該方式對生成的dll的規範有一定的要求否則容易出錯。
Dll的動態呼叫常規程式碼如下:
//#include <Windows.h> #include <afxwin.h> #include <string> #include <vector> //#define _AFxDLL typedef int (*DLLfun)(int, int); int main(){ DLLfun fun1; HINSTANCE hdll; hdll=LoadLibrary("Image Enhance.dll"); //載入dll printf("hdll:%p\n",hdll);//列印dll地址 if(hdll==NULL){ FreeLibrary(hdll);//釋放dll } fun1 = (DLLfun)GetProcAddress(hdll, "sharpen");//獲取函式地址 printf("fun1:%p\n",fun1); if(fun1==NULL){ FreeLibrary(hdll); } int r; r = fun1(4,5);//函式地址 return 0; }
從上面的程式可以看出,dll動態呼叫主要用到三個函式LoadLibrary,GetProcAddress以及FreeLibrary。
1. LoadLibrary是用來載入dll的,格式為
HINSTANCE hdll;
hdll=LoadLibrary("Image Enhance.dll");
呼叫成功則返回函式地址,否則返回0或NULL。
(1)當其調用出錯時,用GetLastError()得到返回值一般為126。使用LoadLibrary()動態載入dll失敗的原因一般分兩種:
1)路徑不對(程式與dll要放在同一資料夾)
2) dll本身錯誤(依賴其他dll)
解決方法:
a. 將DLL與exe放於同一目錄
b. Loadlibrary()與LoadlibraryEx()
c. DLL本身依賴使用depends.exe/Dependency Walker(depends)檢視該DLL依賴哪些DLL
“depends.exe 使用說明”:http://blog.csdn.net/scythe666/article/details/47165533
2. GetProcAddress()是用來獲取函式地址的,呼叫格式
fun1 =(DLLfun)GetProcAddress(hdll, "sharpen");
具體看上面程式或者百度。通常若dll生成規範,可以直接執行成功。失敗則返回0或NULL。
(1)當其調用出錯時,用GetLastError()得到返回值一般為127,表示函式地址獲取失敗。原因基本上是因為函式名(如“sharpen”)在dll中不存在。當函式名沒有拼寫出錯的時候,則是因為dll在生成過程中把函式按不同標準進行修改,如改成了“?? 0sharpen @@
fun1 = (DLLfun)GetProcAddress(hdll, "?? 0sharpen @@[email protected] ");
這種方式呼叫起來很不方便,每次都要去檢視dll,所以我們最好在生成dll的時候就讓函式名變得規範,下文會對dll生成中的注意點進行介紹。
3. FreeLibrary()是用來釋放載入dll時佔用的空間的,由於Loadlibrary()為對dll的顯式載入(又叫動態載入),這種方式不會在用完dll後自動清理dll所佔用的空間,所以我們要手動清除dll所佔用的空間。否則會導致記憶體洩漏。呼叫格式如下:
FreeLibrary(hdll);
以上三個函式的具體使用還可以參考:
“動態載入DLL所需要的三個函式詳解(LoadLibrary,GetProcAddress,FreeLibrary)”
http://www.cnblogs.com/westsoft/p/5936092.html
4.規範化生成dll的注意點
(1)標頭檔案中定義__declspec(dllexport) 時,要加上extern "C",從而規範dll的輸出符合C標準,否則容易生成帶@之類的字串。extern"C"使得在C++中使用C編譯方式成為可能。在“C++”下定義“C”函式,需要加extern“C”關鍵詞。用extern "C"來指明該函式使用C編譯方式。加上extern “C”後,輸出函式的形式為"sharpen",符合預期標準。格式如下:(其中IMG_EXPORTS為自己定義輸出巨集)
#define IMG_EXPORTS extern "C" __declspec(dllexport)
//或者
extern "C" _declspec(dllimport) int calculateLineNum(CString filePath);
但是該過程需要注意一點避免出錯,例如下面生成dll的標頭檔案程式碼中,函式輸出應該寫在“AAA”出現的位置,而不是“BBB”位置,在需要輸出到dll的函式前加上IMG_EXPORTS,如下:
#ifdef IMG_API_EXPORTS
#define IMG_EXPORTS extern "C" __declspec(dllexport)
AAAAAAAAAAAAAAAAA
IMG_EXPORTS int fun1(int a,int b);
#else
#define IMG_EXPORTS __declspec(dllimport)
#endif
BBBBBBBBBBBBBBBBBB
注:使用微軟專用的_declspec (dllexport)
cpp檔案在編譯為OBJ檔案時要對函式進行重新命名,C語言會把函式name重新命名為_name,而C++會重新命名為[email protected]@decoration,extern "C"表示用C語言的格式將函式重新命名,要輸出整個的類,對類使用_declspec(_dllexpot);要輸出類的成員函式,則對該函式使用_declspec(_dllexport)。
注:extern C的作用詳解參考部落格:http://blog.csdn.net/jiqiren007/article/details/5933599
(2)不加extern "C"的情況下,輸出函式名容易變形,靜態呼叫dll完全沒問題,但是顯式呼叫dll容易出錯。除了extern "C",我們還可以新增的標準約定,如_stdcall等。
1)__stdcall呼叫約定
在輸出函式名前加上一個下劃線字首,後面加上一個“@”符號和其引數的位元組數,格式為[email protected]。
2)__cdecl
呼叫約定僅在輸出函式名前加上一個下劃線字首,格式為_functionname。
3)__fastcall呼叫約定在輸出函式名前加上一個“@”符號,後面也是一個“@”符號和其引數的位元組數,格式為@[email protected]。
它們均不改變輸出函式名中的字元大小寫,這和PASCAL呼叫約定不同,PASCAL約定輸出的函式名無任何修飾且全部大寫。
注:關於dll匯出函式名的方式還可以參考以下部落格:
dll匯出函式名的那些事:http://blog.csdn.net/qq_16209077/article/details/51989114
相關推薦
ROS CAN匯流排裝置接入(一)Linux動態庫的顯式呼叫
前提: (1),如果在libpcan安裝正常的話,那麼可以用以下命令查詢到libpcan.so ls /usr/lib/libpcan* 查詢到方可進行api載入。 (2),確保CMakeList.txt 當前目標檔案已加入add_executable...;target_
VS下動態庫dll的顯式呼叫(動態呼叫)
VS下動態庫dll的顯式呼叫 動態庫的載入分兩種形式:分為靜態載入和動態載入。靜態載入時,對應的標頭檔案、DLL,和LIB缺一不可,並且生產的EXE沒有找到DLL檔案就會導致“應用程式初始化失敗”。動態載入只需要dll,通過LoadLibrary()函式進行載入,但該方式對
Linux下靜態、動態庫(隱式、顯式呼叫)的建立和使用及區別
顯式呼叫的動態庫的建立與隱式呼叫相同。(隱式呼叫與靜態庫的使用方法一樣,不需要包含匯出函式的標頭檔案(顯式呼叫也不用包含標頭檔案),只需要在編譯可執行程式時指定庫檔案的路徑)顯式呼叫和隱式呼叫的區別在於:編譯可執行程式時需要指定庫檔案的搜尋路徑,而顯式呼叫編譯可執行程式時不用加上動態庫的搜尋路徑(因為已經在主
動態庫(.dll)的建立與使用———VS編譯器實現
一、動態庫的概念 ①概念:動態庫連結時不復制,程式執行時由系統動態載入到記憶體,供程式呼叫。而且系統只加載一次,可以被多個程式共用。 ②特點: 動態函式庫在編譯的時候並沒有被編譯進目的碼中,需要用到相應的功能,程式碼才會被呼叫到程式中,節約記憶體 動態庫的改變,程式
windows下動態庫dll和靜態庫編譯和使用問題
window下動態庫dll和靜態庫lib問題 windows下動態庫dll和靜態庫lib的聯絡和區別,以及示例匯出個動態庫 https://blog.csdn.net/lifei092/article/details/79630273 問題: 1,生成dll時,同時生成lib是做
PB呼叫.NET/C#開發的動態庫DLL的問題
之前用C#做了一個Dll提供給第三方呼叫(主要為PB使用者)。 pb一直無法呼叫我寫的dll,導致問題排查了3天。 最後找出原因是因為,對方環境沒有安裝.net framework。沒有將dll註冊導致的。
JNA呼叫C動態庫dll、so
1.介紹jna JNA(Java Native Access )提供一組Java工具類用於在執行期動態訪問系統本地庫(native library:如Window的dll)而不需要編寫任何Native/JNI程式碼。開發人員只要在一個java介面中描述目
unity-呼叫動態庫dll-windows篇
1、生成64位的dll 用vs新建個工程,隨便寫個函式 NaviteCode.h #ifndef __NativeCode_H__ #define __NativeCod
利用c#實現dll動態庫,並在c++中呼叫的方法
近期,在進行一個大專案開發。其中涉及多語言協同開發。主要是c#dll和c++dll的開發和應用,其中,需要在c++中呼叫c#dll的內容。現在把開發中的經驗、教訓和注意事項總結整理如下,希望對其他人能有所幫助。 1.建立c#dll,
【HelloCUDA】win10下 首個 cuda9 應用程式 及 靜態庫(.lib) 動態庫(.dll)的引用
環境描述: win10 cuda 9.0 vs2017 vc++2015 redistributable update 3 and Build tools 目標及實現步驟 #1 將 CUDA 核心計算函式以靜態庫的方式為應用程式所用 1.1 新建靜態庫專案 1
vb.net 呼叫動態庫dll
'宣告部分 Public Declare Function Encode Lib ".\LDPC_DEC_DLL.dll" _ (ByRef s As Byte, ByRef c As Byte) As Byte Public Declar
【PE】Windows平臺下為可執行檔案或動態庫dll新增版本資訊
###Date: 2017/9/22 ###Author : SoaringLee 平常我們可以看到在Windows可執行檔案中,右鍵屬性中含有檔案版本,檔名稱和版本等資訊,本文講述怎麼新增這些
【深度學習之Caffe】將模型測試Classification過程生成動態連結庫dll以方便其他專案呼叫
#include "caffe_classify.h" #include "head.h" Classifier::Classifier(const string& model_file,const string& trained_file,const string& mean
C# 調用 C++/CLI (托管模式c++) 的動態庫(DLL)
C++/CLI C# Dll調用 1.創建C++/CLI的動態庫 添加類 右鍵生成後即可生成 CLI_Dll.dll2.創建C#窗口應用程序,引用CLI_Dll.dll,然後就可以像是調用C#生成的的dll調用CLI_Dll.dll。C# 調用 C++/CLI (托管模式c++) 的動態庫(D
Unity3d 載入 C++/CLI (託管模式c++) 的動態庫(DLL)
由於最近開發遊戲尋路A*使用非常頻繁.所以是邏輯上的瓶頸. c#又比c++慢一倍.所以決定上c++.這樣算一種優化吧.哈哈. 關於vs上的vc++.分託管和非託管模式. 託管模式就是 C++/CLI 也就說可以c++使用.net庫. 和 CLR是一起的. 還有就是 非託
使用動態庫DLL匯出類
首先建立一個DLL工程,名稱為ServMgrDll,新建一個類,包含標頭檔案ServConfig.h和cpp檔案ServConfig.cpp。類的程式碼如下:.h:#pragma once /* 如果沒有定義:ServConfigAPI,則ServConfigAPI
動態庫DLL中類的使用
一、DLL中類的匯出 在類名稱前增加 _declspec(dllexport)定義,例如: class _declspec(dllexport) CMath{ .... }; 通常使用預編譯開關切換
Unity Windows&Mac 編譯和除錯外部C#動態庫(DLL)
目標實現 Windows 平臺 工具 Visual Studio 2015 Unity 5.6 Visual Studio 2015 Tools for Unity Python 2.7.9 步驟 建立 C# 類庫工程 引用UnityEngine.dl
qt使用動態庫(DLL)
本文主要講解在QT開發環境中如何使用VC生成的DLL及QT自身生成的DLL。至於其它情況本文不作討論。 連線庫分為2種 (1)動態連線庫,通常有.h .lib .dll三個檔案,功能實現在dll中 (2)靜態連線庫,通常有.h .lib二個檔案,功能實現在lib中 由上可以看
Visual Studio2017動態庫DLL製作與使用
DLL(Dynamic Link Library)檔案為動態連結庫檔案,又稱“應用程式拓展”,是軟體檔案型別。在Windows中,許多應用程式並不是一個完整的可執行檔案,它們被分割成一些相對獨立的動態連結庫,即DLL檔案,放置於系統中。當我們執行某一個程式時,相