程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 淺析C++Builder調用Visual C++ DLL

淺析C++Builder調用Visual C++ DLL

編輯:C++入門知識

使用C++Builder調用Visual C++ DLL 創建的DLL不會比調用C++Builder 建造的DLL 難,首先,Borland 和 Microsoft 在 OBJ 和引入庫的文件格式上不同Visual C++ 使用 COFF 庫格式,而 Borland 使用 OMF 格式。

這就意味著你不能把一個 Microsoft 生成的引入庫添加到C++Builder 的工程裡。感謝 Borland IMPLIB 這個實用工具,文件格式的不同得以克服。
兩個產品在連接名字linker name)習慣上也不同。

這是 C++Builder 調用 Visual C++ DLL 的主要障礙。在 DLL 或 OBJ 裡的每一個函數有一個連接名字。連接器用連接名字在連接期間解決resolve)聲明了原型的函數。如果連接器不能找到它認為是程序需要的連接名字的函數,它將產生一個未解決的外部錯誤unresolved external error)。

關於函數連接名字,Borland 和 Microsoft 在下面兩點上不同:
1- Visual C++ 有時修飾導出的 __stdcall 函數。
2- Borland C++Builder 在引入這個被修飾的函數時,認為是 __cdecl 函數。

那麼,這件事為什麼這樣重要呢?拿分歧#1 __stdcall 調用習慣來說。如果你用 Visual C++ 創建了一個 DLL,它包含一個 __stdcall 修飾的函數叫做 MyFunction(),Visual C++ 將給函數一個連接名字,為 _MyFunction@4。當 Borland 連接器設法解決調用構造這個函數的時候,它認為要找一個名為 MyFunction 的函數。因為 Visual C++ DLL 引入庫不包含叫作 MyFunction 的函數,Borland 連接器報告一個未解決的外部錯誤,意識是沒有找到函數。

解決這三個問題的方法要依賴 Visual C++ DLL 的編譯方式。我把整個過程分為二步。
第1步:識別在 Visual C++ DLL 裡使用的調用習慣為了與命名習慣纏結交戰,你必須首先確定在 DLL 裡函數使用的調用習慣。你可以通過查看 DLL 的頭文件來確定。在 DLL 頭文件裡的函數原型形式如下

第2步:檢查 DLL 裡的連接名字如果在第 1 步中顯示 DLL 利用 __stdcall 調用習慣,你需要進一步檢查 DLL,確定 Visual C++ 在創建它時采用的命名習慣。Visual C++ 默認情況下要修飾 __stdcall 函數,但如果寫這個 DLL 的程序員在他們的工程裡增加一個 DEF 文件,可以阻止命名修飾。如果供應商沒有使用 DEF 文件,你的工會稍微繁瑣一些。
命令行工具 TDUMP 允許你檢查 DLL 導出函數的連接名字。下面向 DLL 調用 TDUMP 的命令。

TDUMP 能報告許多關於 DLL 的信息。我們僅對 DLL 的導出函數感興趣。-ee 命令選項指示 TDUMP 僅列出導出信息。-m 開關告訴 TDUMP 按 DLL 函數的原始格式顯示。如果沒有 -m 開關,TDUMP 將嘗試把修飾過的函數轉化為人們易讀的格式。如果 DLL 很大的話,你應該重定向 TDUMP 的輸出到一個文件裡通過附加的 > MYDLL.LST)。

TDUMP 為源程序清單 A 和 B 的測試 DLL 輸出如下:

  1. bo Dump Version 5.0.16.4 Copyright (c) 1988, 1998 Borland International  
  2. Display of File DLL.DLL  
  3. EXPORT ord:0000='CdeclFunction' 
  4. EXPORT ord:0002='UnknownFunction' 
  5. EXPORT ord:0001='_StdCallFunction@4' 

注意在 __stdcall 函數上的前綴下劃線和後綴 @4。__cdecl 和未指定調用方式的函數沒有任何修飾符。如果 Visuall C++ DLL 編譯的時候帶 DEF 文件,在 __stdcall 函數上的修飾符將不會出現。

  1. C與C++中標准輸入實現方式上的一點區別
  2. C++編譯器如何對Const常量進行分配存儲空間
  3. C++類庫設計的基本構思與方法
  4. 玩轉C++語言的幾種方法
  5. 如何更好的進行C++代碼編制

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved