首先,請參照下面重要的export function name的規則。
__________________________________________________________________
呼 叫 慣 例 原 始 函 式 Borland C++Builder Microsoft Visual C++
__cdecl MyFunc_cdcel _MyFunc_cdcel MyFunc_cdcel
__stdcall MyFunc_std MyFunc_std _MyFunc_std@8
__fastcall MyFunc_fast @MyFunc_fast @MyFunc_fast@8
-----------------------------------------------------------------------
說明:
假如你使用BCB來製作DLL,而你宣告 __declspec(dllexport) MyFunc_cdcel,那麼PE中的export table會記載 _MyFunc_cdcel (有底線)
假如你使用VC來製作DLL,而你宣告 __declspec(dllexport) MyFunc_cdcel,那麼PE中的export table會記載 MyFunc_cdcel (沒有底線)
1/ 我們先針對DLL使用__cdecl的情形來轉換:
由上表可知,BCB對於cdecl convention的function是會在function前面加上 _ 底線。
BCB對於stdcall 的部份則是沒加 _ 。
VC的部份則是相反。
implib -a -c -f mybcb.lib myvc.dll ::a 參數強迫加入 _ alias to MS cdecl
A/ 先透過impdef程式來產生DEF檔(module defintion file)
B/ 根據最上面的表,並探索該dll的pe表頭來對照出export函式是哪一種convention
以__stdcall為例,使用通用的法則:
EXPORTS
_Sub@8 =_Sub @1
則把它修改成如下
EXPORTS
Sub = _Sub@8 @1 ;左邊的Sub已經沒有@8之類的裝飾
修改好後再執行Implib MyBcbStdcall.lib test.def ,就可以得到可用的lib檔了!
相反的,若要使BCB.DLL來給VC++用時,也是先產生def檔,然再查表修改def檔,再由VC自帶的lib /DEF:xxx.def來產生vcl lib檔。
註:def中的右邊是所謂的internal name。是指原函式在compiler後的真實名字。用於link時期的比對,比如在DOS時代若要把C的obj檔與ASM的obj檔link起來時就要注意這名字的吻合。
補充重點: 以上的lib修改好後,都尚需要配合含有extern "C" 這關鍵字的header檔才可以算完成。請參考我另一篇關於extern "C"的文章
Calling convention | VC++ | BCB |
__cdecl | _Function | _Function |
__stdcall | _Function@n | Function |
上表是internal name 的規則
PS. BCB 的 internal name 與 export name 是一樣的。但VC的 internal name 與 export name 不一定一樣!
留言列表