如何使用C++ Builder與VC開發的DLL
首先,請參照下面重要的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的部份則是相反。
所以在製作for BCB lib from VC DLL時需要用下面的方法(針對cdcel的部份):
implib -a -c -f mybcb.lib myvc.dll ::a 參數強迫加入 _ alias to MS cdecl
2/ 通用的轉換方式,可用於__cdecl與__stdcall等情形
A/ 先透過impdef程式來產生DEF檔(module defintion file)
B/ 根據最上面的表,並探索該dll的pe表頭來對照出export函式是哪一種convention
C/ 若def檔內有=號分左右邊,將原左邊變成右邊,再把左邊依Borland C++的export function name規則建立起來。
D/ 若def檔中沒有=號,那麼就直接修改左邊的名稱為Borland C++的export function name規則。
E/ 存檔後再用個自的lib工具來製作lib檔。
F/ 必要的話終極方式就是修改dll檔中的import table
以__stdcall為例,使用通用的法則:
先使用impdef test.def myvc.dll
假使test.def的內容如下
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 不一定一樣!
沒有留言:
張貼留言