上次寫了如何在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文件:
// 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文件:
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,只要注冊它後就可以運行了。
本文配套源碼