做了个简单的COM:调用COM时提示“不支持此接口”的问题(50分)

  • 主题发起人 主题发起人 liuying1129
  • 开始时间 开始时间
L

liuying1129

Unregistered / Unconfirmed
GUEST, unregistred user!
这是COM库单元
library TIServer;

uses
ComServ,
DCPTypeServer_TLB in 'DCPTypeServer_TLB.pas',
AreaIntf in 'AreaIntf.pas' {UnitAuto: CoClass};

exports
DllGetClassObject,
DllCanUnloadNow,
DllRegisterServer,
DllUnregisterServer;

{$R *.TLB}

{$R *.RES}

begin
end.

这是COM接口单元
unit DCPTypeServer_TLB;

{$TYPEDADDRESS OFF} // Unit must be compiled without type-checked pointers.
{$WARN SYMBOL_PLATFORM OFF}
{$WRITEABLECONST ON}
{$VARPROPSETTER ON}
interface

uses Windows, ActiveX, Classes, Graphics, StdVCL, Variants;

const
// TypeLibrary Major and minor versions
DCPTypeServerMajorVersion = 1;
DCPTypeServerMinorVersion = 0;

LIBID_DCPTypeServer: TGUID = '{91ADB6E6-4F4D-11D3-B84B-0040F67455FE}';

IID_IUnitAuto: TGUID = '{91ADB6E7-4F4D-11D3-B84B-0040F67455FE}';
CLASS_UnitAuto: TGUID = '{91ADB6E9-4F4D-11D3-B84B-0040F67455FE}';

// *********************************************************************//
// Declaration of Enumerations defined in Type Library
// *********************************************************************//
// Constants for enum AreaUnit
type
AreaUnit = TOleEnum;
const
auSquareMeters = $00000000;
auSquareCentimeters = $00000001;
auSquareYards = $00000002;
auSquareFeet = $00000003;
auSquareInches = $00000004;
auSquareKilometers = $00000005;
auSquareMiles = $00000006;
auAcres = $00000007;

type

// *********************************************************************//
// Forward declaration of types defined in TypeLibrary
// *********************************************************************//
IUnitAuto = interface;

// *********************************************************************//
// Declaration of CoClasses defined in Type Library
// (NOTE: Here we map each CoClass to its Default Interface)
// *********************************************************************//
UnitAuto = IUnitAuto;


// *********************************************************************//
// Interface: IUnitAuto
// Flags: (256) OleAutomation
// GUID: {91ADB6E7-4F4D-11D3-B84B-0040F67455FE}
// *********************************************************************//
IUnitAuto = interface(IUnknown)
['{91ADB6E7-4F4D-11D3-B84B-0040F67455FE}']
function Convert(Quantity: Double; InUnit: SYSINT; OutUnit: SYSINT): Double; stdcall;
end;

// *********************************************************************//
// The Class CoUnitAuto provides a Create and CreateRemote method to
// create instances of the default interface IUnitAuto exposed by
// the CoClass UnitAuto. The functions are intended to be used by
// clients wishing to automate the CoClass objects exposed by the
// server of this typelibrary.
// *********************************************************************//
CoUnitAuto = class
class function Create: IUnitAuto;
class function CreateRemote(const MachineName: string): IUnitAuto;
end;

implementation

uses ComObj;

class function CoUnitAuto.Create: IUnitAuto;
begin
Result := CreateComObject(CLASS_UnitAuto) as IUnitAuto;
end;

class function CoUnitAuto.CreateRemote(const MachineName: string): IUnitAuto;
begin
Result := CreateRemoteComObject(MachineName, CLASS_UnitAuto) as IUnitAuto;
end;

end.

这是COM实现单元
unit AreaIntf;

interface

uses
Windows, ActiveX, Classes, ComObj, DCPTypeServer_TLB, StdVcl;

type
TUnitAuto = class(TTypedComObject, IUnitAuto)
protected
function Convert(Quantity: Double; InUnit, OutUnit: SYSINT): Double;
stdcall;
{Declare IUnitAuto methods here}
end;

implementation

uses ComServ;

function TUnitAuto.Convert(Quantity: Double; InUnit,
OutUnit: SYSINT): Double;
const
AreaFactor:array[auSquareMeters..auAcres]of double=
(1,2,3,4,5,6,7,8);
begin
result:=Quantity*AreaFactor[InUnit]/AreaFactor[OutUnit];
{ Stubbed out because we're only interested in the type library }
end;

initialization
TTypedComObjectFactory.Create(ComServer, TUnitAuto, Class_UnitAuto,
ciMultiInstance, tmApartment);
end.

下面是调用
procedure TForm1.Button1Click(Sender: TObject);
var
V:variant;
begin
V:=CreateOleObject('DCPTypeServer.UnitAuto');//<---执行到这里时就提示“不支持此接口”
showmessage(floattostr(V.convert(1.0,0,1)));
end;
 
做过COM应该很简单的啊,里面就一个方法而已
 
首先Com注册了没有?
1.regsvr32 盘符:/路径/你的dll
2.打开工程,直接在delphi里有 run -> Register ActiveX Server这一项
 
已经注册了
 
是COM+程序吧,注意设置好权限。
 
V:=CoUnitAuto.Create;
 
var
v:variant;
begin
V:=CoUnitAuto.Create;
end;
一样提示“不支持此接口”
 
你首先需要把'DCPTypeServer_TLB.pas 这个文件加到新建的工程里边
add project 这个DCPTypeServer_TLB.pas 单元
var
v:IUnitAuto;
begin
V:=CoUnitAuto.Create;
end;
这样是让程序知道这个接口. COM 本来就是dll与EXE 文件之间通过接口进行通信用的技术 dll与访问他的程序是驻留在同一进程里的因此称为进程内COM 也可以是2个EXE之间 这样就叫做进程外COM
 
还得注意权限问题
 
注意:在Fform1单元中use单元'DCPTypeServer_TLB.pas

下面是调用
procedure TForm1.Button1Click(Sender: TObject);
var
V:IUnitAuto;
begin
V := CoUnitAuto.CreateRemote('RemoteMachineName'); //COM在远程机器
V := CoUnitAuto.Create; //COM在本机
showmessage(floattostr(V.convert(1.0,0,1)));
end;
 
多人接受答案了。
 

Similar threads

后退
顶部