?? 20000922008.htm
字號:
<HTML>
<HEAD>
<TITLE>在VB中如何調用C++Builder創建的DLL</TITLE>
<META content="MSHTML 5.00.2314.1000" name=GENERATOR>
</HEAD>
<BODY aLink=#FF0000 bgColor=#ffffff leftMargin=0 link=#187800 topMargin=0
vLink=#990099>
<div align="center">
<table width="744" border="0" cellspacing="0" cellpadding="0" height="76">
<tr>
<td>
<center>
<h2><font size="3"><br>
在VB中如何調用C++Builder創建的DLL</font><font color="#0000c0"> </font></h2>
<h3><font size="2">合肥電子工程學院計算中心 <br>
李 強 </font></h3>
</center>
<p align="left"><font color=#ffffff>----</font> C++Builder具有強大的創建Dynamic
Link Library 的能力。許多C++Builderr的書藉在創建使用DLL的章節中直接引用的聯機文檔中的例子。但在Visual
C++和VB中直接調用該示例生成的DLL卻出現了一些問題,現在我們結合在VB中的調用給出解決方法。示例代碼如下所示: <xmp>//////////////////////////
// Mydll.cpp ////////////////////////// double dblValue(double); double
halfValue(double); extern __declspec(dllexport) double changeValue(double,
bool); double dblValue(double value) { return value * value; }; double
halfValue(double value) { return value / 2.0; } double changeValue(double
value, bool whichOp) { return whichOp ? dblValue(value) : halfValue(value);
} </xmp><font color=#ffffff>----</font> 對于外部調用函數加入了__declspec(dllexport)修飾成分,這和Visual
C++是相同的,說明該函數將自動從DLL中導出,并對任何調用程序可用。然后,對上述代碼在C++Builder環境中編譯鏈接生成Mydll.DLL和Mydll.Lib,并將Mydll.DLL拷入Windows\system目錄下(由于VB默認的查找DLL的目錄為Windows\system)。
<p align="left"><font color=#ffffff>----</font> 在VB5.0中新建一個應用,并添加一個模塊,在模塊中將函數調用說明如下:
<xmp>Declare Function changeValue Lib "mydll" (ByVal Value As Double,
ByVal WhichOp As Boolean) As Double </xmp><font color=#ffffff>----</font>
然后在窗體的一個按鈕的Click事件中調用changeValue,對該函數進行測試。測試代碼如下: <xmp> Dim aa As Double
aa = changeValue(10,True) </xmp><font color=#ffffff>----</font> 實際運行中出現了“找不到DLL入口點changeValue
in MyDll”的錯誤信息。
<p align="left"><font color=#ffffff>----</font> 這時利用資源管理中的快速查看功能查看Mydll.DLL,在Export
Table中有關信息如下:
<div align="left">
<pre> Ordinal EntryPoint Name
0000 00013c4 @changeValue$qd4bool
</pre>
<font color=#ffffff>----</font> 發現changeValue函數除了函數名外之外前后還有@、$等附加字符。查閱有關資料得知這是由于編譯器對C++名字的修整造成的,由于Microsoft的Visual
C++和Borland的C++ Builder的修整方式不同,在分別修整C++名字的時候,對于相同的函數當然就不會出現相同的名字。好再C++語言通過從系統內定義的函數和對象中刪除修整,從而有效地解決這一問題。
</div>
<p align="left"><font color=#ffffff>----</font> 將語句extern “C” 放置在程序中的代碼塊內,編譯器就將不會修整這塊代碼。這時將Mydll.cpp有關代碼修改如下:
<xmp>extern “C” __declspec(dllexport) double changeValue(double, bool);
</xmp><font color=#ffffff>----</font> 再次查看重新生成的Mydll.DLL,這時Export table中的有關信息如下:
<xmp> Ordinal EntryPoint Name 0000 00013c4 _changeValue </xmp><font color=#ffffff>----</font>
@、$等字符沒有了,但在函數名多了一條”_”線。將Mydll.DLL重新拷入windows\system目錄下,并在VB的模塊中修改調用說明如下:
<xmp>Declare Function changeValue Lib "mydll" Alias “_changeValue” (ByVal
Value As Double, ByVal WhichOp As Boolean) As Double </xmp><font color=#ffffff>----</font>
運行VB測試程序,出現”DLL 調用約定錯誤”的錯誤提示信息。說明changeValue找到了,只是調用約定不對。我們知道調用約定有__fastcall、__pascal、__stdcall、__cdecl四種方式,而在C++Builder中默認調用約定為__cdecl方式,而VB中調用約定為__stdcall方式。
<p align="left"><font color=#ffffff>----</font> 再將Mydll.cpp的代碼修改如下: <xmp>extern
“C”__declspec(dllexport) double __stdcall changeValue(double, bool);
…… double __stdcall changeValue(double value, bool whichOp) { return
whichOp ? dblValue(value) : halfValue(value); } …… </xmp><font color=#ffffff>----</font>
這時查看重新編譯鏈接生成的Mydll.DLL,Export table中的有關信息如下:
<div align="left">
<pre> Ordinal EntryPoint Name
0000 00013c4 changeValue
</pre>
<font color=#ffffff>----</font> 發現函數名前的“_”線也沒有,再次修改VB中調用說明如下: <xmp>Declare
Function changeValue Lib "mydll" (ByVal Value As Double, ByVal WhichOp
As Boolean) As Double </xmp><font color=#ffffff>----</font> 運行測試程序,運行結果正確。
</div>
<p align="left"><font color=#ffffff>----</font> 后又將__stdcall調用約定方式改__pascal調用約定方式,運行結果同樣正確,但改為__fastcall調用約定方式不行。
<p align="left"><font color=#ffffff>----</font> 上面所討論的解決方法不僅適用VB,該方法同樣適樣Visual
C++,這樣使Visual C++和C++ Builder 不同編譯器生成的DLL可以互相兼容。 </p>
</td>
</tr>
</table>
</div>
</BODY></HTML>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -