2012年11月21日星期三

【转】Delphi下可以实现dispinterface么?该如何解决

Delphi下可以实现dispinterface么?
据说dispinterface就是纯分发接口,未实现IUnknown的
在用连接点的时候,需要给它一个dispinterface的接口,通常就是给它IDispatch接口,但是因为不能实现dispinterface接口,弄得每次QueryInterface的时候要比较GUID,如果是某个dispinterface,就返回对应的IDispatch,而不能使用QueryInterface的默认实现。

大家在自己手动使用事件连接点的时候一般怎么干的啊?还有,有没有好一点的办法能够直接将Invoke调用映射到一系列方法上去?Delphi编译器有没有对它的默认实现?

------解决方案--------------------------------------------------------
Delphi帮助就有:
type
IStringsDisp = dispinterface
['{EE05DFE2-5549-11D0-9EA9-0020AF3D82DA}']
property ControlDefault[Index: Integer]: OleVariant dispid 0; default;
function Count: Integer; dispid 1;
property Item[Index: Integer]: OleVariant dispid 2;
procedure Remove(Index: Integer); dispid 3;
procedure Clear; dispid 4;
function Add(Item: OleVariant): Integer; dispid 5;
function _NewEnum: IUnknown; dispid -4;
end; 
------解决方案--------------------------------------------------------
楼主理解有点不对

IUnkonwn 是最底的带 GUID 接口 等价于 IInterface, 派生于 interface 用于 COM 实现时转义为 IUnknown, delphi 接口有一个广意性, 它不一定非要是 COM 对像

IDispatch 叫调度接口, 定义为
IDispatch = interface(IUnknown)
['{00020400-0000-0000-C000-000000000046}']
function GetTypeInfoCount(out Count: Integer): HResult; stdcall;
function GetTypeInfo(Index, LocaleID: Integer; out TypeInfo): HResult; stdcall;
function GetIDsOfNames(const IID: TGUID; Names: Pointer;
NameCount, LocaleID: Integer; DispIDs: Pointer): HResult; stdcall;
function Invoke(DispID: Integer; const IID: TGUID; LocaleID: Integer;
Flags: Word; var Params; VarResult, ExcepInfo, ArgErr: Pointer): HResult; stdcall;
end;
其中 2 个方法最为重要, GetIDsOfNames和 Invoke

注意 GetIdsOfNames 中参数  
Names 是一个 c 数组
DispIDs 实际是一个整形数组
这里面的内容就是 函数名 <--> Disp id 之间的关系

现在是 Invoke 参数, 跟上面很有关系
DispId 是用 name 查出来的 Id, 并不支持 Name 调用
... 下面是参数之类

换句话说你如果直接知道 DispID 就可以直接调用 Invoke 而不必用 GetIDsOfNames(用函数名称取得 id)

没有评论: