關於dll的匯出符號

2021-06-19 18:39:01 字數 2045 閱讀 1165

函式原型:

extern "c" __declspec(dllexport) int _stdcall gzipcompression(const char *, int , char *, int )

編譯後的匯出符號:

_gzipcompression@16

函式原型:

extern "c" __declspec(dllexport) int _cdecl gzipcompression(const char *, int , char *, int )

編譯後的匯出符號:

gzipcompression

函式原型:

__declspec(dllexport) int _cdecl gzipcompression(const char *, int , char *, int )

編譯後的匯出符號:

?gzipcompression@@yahpbdhpadh@z

函式原型:

__declspec(dllexport) int _stdcall gzipcompression(const char *, int , char *, int )

編譯後的匯出符號:

?gzipcompression@@yghpbdhpadh@z

extern "c" 按照c的方式進行符號修飾

c++方式進行的符號修飾相對複雜

::loadlibrary(lpctstr szdll)的返回值 既為對應dll在程序虛擬位址空間中的虛擬位址

首個自定義被載入的dll 對應的位址應為0x10000000

::getprocaddress() 中所制定的符號 對應為dll的匯出符號 而不是dll中函式的圓型

以上四種呼叫慣例 和 兩種編譯方式所產生出的符號均不相同

僅有呼叫慣例為_cdecl 符號修飾方式為c的宣告才能產生和函式原型相對應的符號(*.def 檔案的作用)

按照以上四種方式編譯出來的dll

如果均以

::getprocaddress(::loadlibrary("*.dll"), "gzipcompression")
方式進行函式獲取  僅有extern "c" + _cdecl 的方式編譯的dll才能獲取的到位址

其他方式編譯出的dll 因為符號不匹配 getprocaddress的返回值均為空

在c#中有所不同

如果按照extern "c" _cdecl的方式編譯

[dllimport("compressor.dll", entrypoint = "gzipcompression", exactspelling = false, callingconvention = callingconvention.cdecl)]

[dllimport("compressor.dll", entrypoint = "gzipcompression", exactspelling = false, callingconvention = callingconvention.stdcall)]

都能進行正確的呼叫

而按照extern "c" _stdcall的方式編譯

[dllimport("compressor.dll", entrypoint = "gzipcompression", exactspelling = false, callingconvention = callingconvention.stdcall)]

能正常執行

[dllimport("compressor.dll", entrypoint = "gzipcompression", exactspelling = false, callingconvention = callingconvention.cdecl)]

的方式將會產生執行時的異常

system.entrypointnotfoundexception

而以c++方式編譯(沒有 extern "c" 宣告)得到的符號 無論_cdecl , _stdcall 均無法進行呼叫

使用dumpbin工具檢視dll匯出符號

每次使用dumpbin都需要在網上搜尋一下再使用,效率低,寫部落格備忘,加深記憶。dumpbin微軟幫助文件介紹 參考資料 啟動方式有兩種 一 找到dumpbin.exe路徑,然後啟動cmd.exe,定位到當前目錄。這種方式需要把待檢視的dll的全路徑寫出來。二 進入vs開發環境,然後tools v...

關於Dll 匯出函式名 ZZ

使用dependency看dll的匯出函式的名字,會發現有一些有意思的東西,這大多是和編譯dll時候指定dll匯出函式的匯出符有關係。當你使用extern c 的情況下 stdcall會使匯出函式名字前面加乙個下劃線,後面加乙個 再加上引數的位元組數,比如 fun 4就是4個位元組 fastcall...

DLL匯出函式

經常使用vc6的dependency檢視dll匯出函式的名字,會發現有dll匯出函式的名字有時大不相同,導致不同的原因大多是和編譯dll時候指定dll匯出函式的界定符有關係。vc 支援兩種語言 即c c 這也是造成dll匯出函式差異的根源 我們用vs2008新建個dll工程,工程名為 testdll...