上次写了如何在VC6.0下对Delphi写的COM进行调用,原本想马上写如何在Delphi中调用VC6.0开发的COM时,由于在写事例程序中碰到了个很怪的问题,在我机子上用VC写的接口程序编译能通过。但是调用就会出现问题,(在VC下调用也是一样的出现)。但是用Delphi写的接口程序编译后,不管是在VC下还是在Delphi下调用都没有问题。后来我把VC开发的接口程序编译后,拷贝到其它机子上试,怪事,完全没有问题了。总结后才知道是我机子有点问题。我到现在还没有解决为什么在我的机子上不行,在其它机子上可以。(如果哪位朋友有什么见意,请和我联系,我想这个问题很有可能是因为注册的原因)不多说了。还是说正事吧!

在VC6.0下开发接口时,会生成一个对应文件名.idl(Interface Definition)接口描述文件。(IDL其语法也很简单,但它在接口的开发中是很重要的。我看过本书,一个对COM很熟的牛XX老外就说,开发COM一切从IDL开始。当然了我们可不是这样的。因为我们不牛XX。所以办不到。还是交给软件写吧!)得到这个IDL文件后,可用IDLtoPas.exe工具(NND,我找这个工具找了半年都有没找到,现在也没有,听说在Delphi6.0中有。所以只有手工把IDL文件用Pascal来描述,也不难,都有是符号的转换工作),把IDL文件转成用Pascal描述的文件。这样我们就可以对其接口进行调用了。当然调用接口时,少不了要接口的.DLL文件和.IDL文件,IDL文件用来生成对应的Pascal文件,生成好后,IDL就可以不要了。而.Dll文件是接口编译后的动态库。这个大家都有知道。好就讲这么多。还是给个小例了吧!

1、用VC6.0生成一个接口程序,在这里我就不多说,我生成的这个程序只有一个接口叫ITestCom其中有一个方法为:ShowMsg(),显示一个消息对话框。

2、对其上面生成的程序进行编译,把生成的IDL文件用在Delphi下用Pascal描述:

VC生成的IDL文件:




1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29


30


31


32


33


34


35


36


37


38


39




​// MaAtl.idl : IDL source for MaAtl.dll​


​//​


 


​// This file will be processed by the MIDL tool to​


​// produce the type library (MaAtl.tlb) and marshalling code.​


 


​import ​​​​"oaidl.idl"​​​​;​


​import ​​​​"ocidl.idl"​​​​;​


​[​


​object,​


​uuid​​​​(78313A6E-FBA7-11D5-8094-00E04C4EA60F),​


​dual,​


​helpstring(​​​​"ITestCom Interface"​​​​),​


​pointer_default(unique)​


​]​


​interface ITestCom : IDispatch​


​{​


​[id(1), helpstring(​​​​"method ShowMsg"​​​​)] ​​​​HRESULT​​ ​​ShowMsg();​


​};​


 


​[​


​uuid​​​​(78313A62-FBA7-11D5-8094-00E04C4EA60F),​


​version(1.0),​


​helpstring(​​​​"MaAtl 1.0 Type Library"​​​​)​


​]​


​library MAATLLib​


​{​


​importlib(​​​​"stdole32.tlb"​​​​);​


​importlib(​​​​"stdole2.tlb"​​​​);​


 


​[​


​uuid​​​​(78313A6F-FBA7-11D5-8094-00E04C4EA60F),​


​helpstring(​​​​"TestCom Class"​​​​)​


​]​


​coclass TestCom​


​{​


​[​​​​default​​​​] interface ITestCom;​


​};​


​};​



Delphi手工转换的Pascal文件:




1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28


29


30


31


32


33


34


35


36


37


38


39


40


41


42


43


44


45


46


47


48


49


50


51


52


53


54


55


56


57




​unit MaAtlDll_TLB;​


 


​// *******************************************************//​


​const​


​// TypeLibrary Major and minor versions​


​MaAtlMajorVersion = 1;​


​MaAtlMinorVersion = 0;​


 


​LIBID_MaAtl: TGUID = ​​​​''​​​​''​​​​{78313A62-FBA7-11D5-8094-00E04C4EA60F}​​​​''​​​​''​​​​;​


 


​IID_ITestCom: TGUID = ​​​​''​​​​''​​​​{78313A6E-FBA7-11D5-8094-00E04C4EA60F}​​​​''​​​​''​​​​;​


​CLASS_TestCom: TGUID = ​​​​''​​​​''​​​​{78313A6F-FBA7-11D5-8094-00E04C4EA60F}​​​​''​​​​''​​​​;​


​type​


 


​// *******************************************************//​


​// Forward declaration of types defined in TypeLibrary ​


​// *******************************************************//​


​ITestCom = interface;​


 


​// *******************************************************//​


​// Declaration of CoClasses defined in Type Library ​


​// (NOTE: Here we map each CoClass to its Default Interface) ​


​// *******************************************************//​


​TestCom= ITestCom;​


 


 


​// *******************************************************//​


​// Interface: IMaAtlCom​


​// Flags: (256) OleAutomation​


 


​// *******************************************************//​


​ITestCom = interface(IDispatch)​


​[​​​​''​​​​''​​​​{78313A6E-FBA7-11D5-8094-00E04C4EA60F}​​​​''​​​​''​​​​]​


​function ShowMsg(): HResult; stdcall;​


​end;​


 


​// *******************************************************//​


​CoTestCom = ​​​​class​


​class​​ ​​function Create: ITestCom;​


​class​​ ​​function CreateRemote(​​​​const​​ ​​MachineName: string): ITestCom;​


​end;​


 


​implementation​


 


​uses ComObj;​


 


​class​​ ​​function CoTestCom.Create: ITestCom;​


​begin​


​Result := CreateComObject(CLASS_TestCom) as ITestCom;​


​end;​


 


​class​​ ​​function CoTestCom.CreateRemote(​​​​const​​ ​​MachineName: string): ITestCom;​


​begin​


​Result := CreateRemoteComObject(MachineName, CLASS_TestCom) as ITestCom;​


​end;​


 


​end.  ​



看它们转换是不是很简单呀!

3、生成一个Delphi工程,在引用中引用刚才手工写的描述文件MaAtlDll_TLB文件。这样引用单元中就可以定义接口如入:

var

pS : ITestCom;

这样就可以创建接口:

pS := CreateComObject(CLASS_TestCom) as ITestCom;//如果在编译中提示没定义 //CreateComObject()这是因为你在引用中没引用ComObj单元。

调用方面ShowMsg();

别忘了退出时把接释放呀!

pS := nil;

对工程进行编译,还不能运行。因为你还没有注册我们的接口maAtl.dll。用regsrv32进行注册后就可以运行了。

谢谢能抽空看,如果有什么问题可写信给我。没有VC的朋友,不能编译MaAtl时,在DyVCcom下有编译好的MaAtl.dll,只要注册它后就可以运行了。