公告

國明的網路筆記

2016年8月8日 星期一

如何使用C++ Builder與VC開發的DLL

資料來源:http://aftcast.pixnet.net/blog/post/22191720-使用vc與bcb開發的dll
如何使用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 不一定一樣!

沒有留言:

張貼留言