分類: c /c++程式設計學習
vc++ ms
2011-05-26 15:04
1437人閱讀收藏
舉報dll
delphi
api編譯器
pascal
winapi
1.dll編譯後匯出函式名稱改編
在編寫乙個dll後,為了能被別的程式呼叫,需要將被使用的函式匯出;
但是一般的編譯器都會將到處函式名稱改編;
例如:在vc中新建乙個空的win32 dll工程,然後新增下面的檔案;
[cpp]view plain
copy
#ifdef dll_api _declspec(dllexport)
#else
#define dll_api _declspec(dllexport)
#endif
dll_api int
add(
inta,
intb);
[cpp]view plain
copy
#include "dll1.h"
dll_api int
add(
inta,
intb)
編譯以後,得到dll1.dll與dll1.lib;使用dumpbin.exe或者是depends工具檢視發現,
dll1.dll中的到處函式名稱為:?add@@yahh@z ;這個新的函式名稱是c++編譯器對add函式的名稱進行了改編,
而且不同的編譯器的改編規則也不一樣,這就導致在通過add函式名對函式進行呼叫時無法找到add函式,
因為此時add的函式名稱已經被改編;
2.限定匯出函式名稱
為了解決c與c++能在不同編譯器之間正常呼叫dll,所以我們希望dll在編譯過程中不要對函式名稱進行改編;
我們可以在定義匯出函式時,加上限定符 extern "c"
我們把上面的例子修改下:
[cpp]view plain
copy
#ifdef dll_api extern "c" _declspec(dllexport)
#else
#define dll_api extern "c" _declspec(dllexport)
#endif
dll_api int
add(
inta,
intb);
[cpp]view plain
copy
#include "dll1.h"
dll_api int
add(
inta,
intb)
我們再次編譯得到dll1.dll,通過工具檢視其到匯出函式發現,此時的add函式的匯出名稱仍然是add;
這樣我們就可以在其他編譯器上直接通過add呼叫該函式了;
3.__stdcall關鍵字將使限定無效
如果我們在第二個的基礎上給函式加上__stdcall關鍵字,匯出函式的名稱將仍然被改編;
如果沒有新增__stdcall關鍵字,那麼函式呼叫約定為c呼叫約定。如果加了__stdcall標準呼叫約定,
就是winapi呼叫約定,也就是pascal呼叫約定,這種約定與c呼叫約定不一樣。
[cpp]view plain
copy
#ifdef dll_api extern "c" _declspec(dllexport)
#else
#define dll_api extern "c" _declspec(dllexport)
#endif
dll_api int
__stdcall add(
inta,
intb);
[cpp]view plain
copy
#include "dll1.h"
dll_api __stdcall int
add(
inta,
intb)
重新編譯,然後通過工具檢視dll的匯出函式,發現名稱為: _add@8;
也就是說如果函式的呼叫約定發生變化,即使在宣告時使用了 extern "c"限定符,函式名稱仍然會
改編;c語言與delphi的呼叫約定是不一樣的,delphi使用的是pascal呼叫約定,如果我們要用c寫乙個dll供delphi使用,
那麼在匯出函式時應指定其使用標準的函式呼叫約定,但此時 匯出函式名稱就會被改編;
在這種情況下,我們需要通過乙個稱為模組定義檔案(def)的方法解決名稱被改編的問題;
在上面例子的基礎上,我們給這個工程新增乙個字尾為def的檔案dll1.def;然後新增如下**:
[c-sharp]view plain
copy
library "dll1"
exports
add
此檔案中library指定動態鏈結庫的內部名稱,該名稱與生成的動態鏈結庫名稱要匹配;
exports下面就是要匯出的函式;
如果匯出的函式名稱與原始檔中的函式名稱不一樣可以通過下面的語法指定匯出函式名稱:
entryname = internalname
編譯時,編譯器會按照def中指定的函式名稱匯出函式;
重新編譯,通過工具檢視dll1.dll中的匯出函式為add了;
DLL匯出函式名稱改編的解決方法
1.dll編譯後匯出函式名稱改編 在編寫乙個dll後,為了能被別的程式呼叫,需要將被使用的函式匯出 但是一般的編譯器都會將到處函式名稱改編 例如 在vc中新建乙個空的win32 dll工程,然後新增下面的檔案 cpp view plain copy ifdef dll api declspec dl...
c 建立dll匯出函式名稱
extern c 的作用是宣告以c語言的格式編譯當前 上 兩個函式,分別以c和c 格式編譯,看看效果是什麼 extern c 與 預設c 方式的區別 extern c declspec dllexport void func1 c declspec dllexport void func1 cpp ...
dll的匯出 解決函式名稱改寫帶來的問題
因為c 要支援函式過載功能,所以實際編譯時會對函式的名稱進行改寫。所以我們要加extern c 來修飾乙個函式,讓該函式不被重寫。但是,如果使用標準呼叫方式 stdcall來修飾的函式即使使用了extern c 來限定,仍然會把名字進行改寫,這個時候可以使用def模組定義檔案來限定函式的名稱,不讓編...