如何在C++Builder中使用Delphi控件
上海铁道大学 施江杰

----Delphi的出现将一大批程序员带入了Windows下的可视化编程，为一些C&C++的死党程序员所羡慕、感叹。
直到C++Builder的出现这些Programer才用到了梦寐以求的编程工具，也将一些不得已"投敌"到Delphi下的程
序员又拉回到C++的怀抱。她正真将Windows下的可视化编程和面向对象编程语言有机的融合在一起。但是由
于C++Builder面市时间较短固而可用的控件不多，而且控件的使用也只针对某一版本，相互之间的可互用性
不好，除非你有SourceCode；对于Delphi就更不用说了，C++Builder根本不能用，当然如果你有SourceCode
那么你可以转写成C++Builder的控件，不过你还得经过n遍的Complie…m遍的Step&Go…最后※☆▲＃＼↓。
----Delphi拥有强大的控件群，如何使用这些控件一直苦恼着我们这些C++Builder的追随者，我通过一些项
目的实践掌握了一些如何在C++Builder中使用Delphi控件的方法。
----我的使C++Builder使用DelphiVCL类库的方法基于Windows中较通用的DLL方式。在实际应用中找到了将
VCL控件转化为DLL库，在C++Builder动态调用DLL。此法适用于非可视VCL控件。
----假令在Delphi中有一Sample控件，有属性Actived、Pro1、Pro2，欲将这个控件转到C++Builder中使用。
一：Delphi中DLL的制作
在Delphi中新建一DLL项目SampleDLL，时在此项目中Create一个新的类TTtempcomp基类为TComponent即也为
一个控件，在其中加入一个constructorCreate1，但不作任何动作；在DLL中加入要导出的属性的Function
（Actived、Pro1、Pro2）&Create、Destroy的框架，Exports中加入导出的Function、Procdure名称；在DLL
的主过程中对TTempcomp的实例temp1进行Create1，另外保存出口和设置ExitProc；在OpenSample的函数中加
入HwCtrl:=Sample1.Create(temp1)对Sample进行实例化，对CloseSample和其它属性加入相应的语句；
二：C++Builder中DLL的使用
将Delphi中生成的DLL用implib生成LIB文件加入C++Builder的工程文件；
在头文件中加入
extern "C" __declspec(dllimport) bool _stdcall OpenSample(void);
extern "C" __declspec(dllimport) void _stdcall CloseSample(void);
extern "C" __declspec(dllimport) bool _stdcall Actived (void);
extern "C" __declspec(dllimport) int _stdcall Pro1 (void);
extern "C" __declspec(dllimport) int _stdcall Pro2 (void);
在OpenSample后你就可以使用Delphi中的属性Actived、Pro1、Pro2
三：参考DLL Source如下：
library SampleDLL；
uses
SysUtils， Classes， Sample；
TYPE
TTempcomp = class(TComponent)
private
public
constructor Create1；
published
end；
var
Sample1 :Sample；
SaveExit :Pointer；
temp1 :TTempcomp；
constructor TTempcomp.Create1；
begin
// inherited Create(self)；
end；
/==============================================
function OpenSample: Boolean； stdcall； export；
begin
HwCtrl:= Sample1.Create(temp1)；
If Sample1.Actived then result:=true；
end；
procedure CloseSample； stdcall； export；
begin
Sample1.Destroy；
end；
function Actived: Boolean； stdcall； export；
begin
result:=Sample1.Actived；
end；
function Pro1: Interger； stdcall； export；
begin
result:= Sample1.Pro1;
end；
function Pro2: Interger； stdcall； export；
begin
result:= Sample1.Pro2;
end；
/==============================================
procedure libexit； far
begin
if Sample1.Actived =true then
Sample1.Destroy；
ExitProc:=SaveExit；
temp1.Destroy；
end；
exports
OpenSample，CloseSample，Actived ，Pro1，Pro2；
begin
temp1:=TTempcomp.Create1；
SaveExit:=ExitProc；
ExitProc:=@libexit；
end.
----解释：
----因为VCL控件都继承于TComponent，TComponent的构造函数需要一个AOwner并且也是TComponent，VCL控
件的Create、Destroy都由控件的拥有者来动作，也就是AOwner；所以我在此DLL中新设置了一个TTempcomp类
继承于Tcomponent且性设置了一个constructor（构造函数）Create1，而实际构造时什么都不做，以次作为要
Create的Aowner；
----其他还有一种办法就是用Application作为Aowner但是它是基于Tform的作出来的DLL太大；
----其实，Inprise（原Borland）尽可以象MicroSoft一样用一些象DCOM类似的组件形式使得产品在同一产品
时代保持一定的互用性，来增加产品群的生命力.