⓪編著 :蕭沖


首先,請參照下面重要的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 不一定一樣!

創作者介紹
創作者 aftcast 的頭像
aftcast

蕭沖的書房

aftcast 發表在 痞客邦 留言(1) 人氣()


留言列表 (1)

發表留言
  • Hukai
  • 謝謝大大

    剛從delphi.K文章中找到這裡...用文中修改def方式 解決了困擾我好幾天的dll問題 感恩*∞