顯式呼叫dll檔案中的函式居然crash了

2021-10-06 03:47:16 字數 1003 閱讀 6276

windows系統下,呼叫dll檔案裡的函式,無非2種方法,一種就是直接包含標頭檔案,編譯連線dll檔案對應的lib檔案。另外一種,就是顯式呼叫:在**裡load這個dll檔案,宣告函式指標,並繫結dll檔案裡的某函式。

顯式呼叫在程式設計時,還是有很多使用場景的。比如說,需要同時呼叫2個廠家的sdk庫函式,無奈的很,這2個sdk離大部分函式居然是同名的,傳引數也相同,甚至api的作用都是一致的。大家估計想起了山寨,嘿嘿。動態load不同的dll檔案,呼叫api的過程都是相同的,在這個情況下使用顯示呼叫無疑是比較好的方法。

使用了qt裡的api介面,注意:此介面在mingw編譯器下,都是正常工作的,但是更換msvc的編譯器後就不正常了。

qlibrary lib("***x.dll");
此次顯式呼叫api時,居然出現隨機crash了。確實是隨機crash,cdb顯示的資訊是指標越界了。除錯很多次,但是幾乎每次死的地方都不一樣。

review**,開始分析。

1. 檢查了dll檔案的load,返回值正常;

2. 檢查函式繫結,似乎也正常;

func func = (func)lib.resolve("func");
3. 檢查函式指標的宣告

/* wrong */

typedef dword (*vci_opendevice)(dword, dword, dword);

/* correct */

typedef dword (__stdcall *vci_opendevice)(dword, dword, dword);

發現問題,關鍵字__stdcall丟失了,詢問了下,為什麼去掉了__stdcall。答曰,編譯不過,所以去掉了。此關鍵字__stdcall新增後,呼叫正常了。

mingw編譯器和msvc編譯器,對語法的約定要求上有一些不同。更換編譯器後,不能因為編譯報錯,就簡單粗暴的去掉某一些關鍵字,而應該多研究語法的異同。否則帶來的除錯工作,可能是災難性的。

dll檔案的隱式呼叫和顯式呼叫(方法示例)

隱式呼叫 隱式呼叫有兩種方法 1 需要dll檔案 lib檔案和標頭檔案 示例 declspec dllimport int add int a,int b declspec dllimport int subtract int a,int b 匯出乙個c 類 class declspec dllim...

Qt隱式 顯式呼叫DLL

下面是我對qt隱式 顯式呼叫dll一點理解,我參考的相關 會在下面羅列出來 顯示呼叫 這裡我覺得的例子挺好的,使用qt建立了乙個加法函式和查詢頁面並封裝成dll以供qt呼叫。在標頭檔案 裡申明dll共享介面 include mytestdll global.h include qdialog.h e...

Dll的顯式和隱式呼叫

隱式呼叫 需要把生成動態鏈結庫時生成的.lib檔案加入到工程中去,在使用dll時,只需說明一下就可以直接呼叫dll中的函式,像呼叫程式內部的函式一樣 顯示呼叫 需要使用loadlibrary方式將自己生成的dll檔案先載入進來,在通過loadlibrary返回的hinstance,呼叫getproc...