首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

怎么通过接口的DispID 获取方法名

2012-02-24 
如何通过接口的DispID 获取方法名?最近研究了Delphi RTTI想要实现一个类似TAutoObject功能的类经过以下试

如何通过接口的DispID 获取方法名?
最近研究了Delphi RTTI
想要实现一个类似TAutoObject功能的类
经过以下试验分析
Delphi 的双重接口的调用模式大致如下

Delphi(Pascal) code
  //接口  ITest = interface(IDispatch)  ['{C8E5E6FF-FBF2-4397-A4F3-8041DF9548E8}']    function Test: Boolean; stdcall;  end;  {$m-}{$METHODINFO OFF}  //disp接口  ITestDisp = dispinterface  ['{C8E5E6FF-FBF2-4397-A4F3-8041DF9548E8}']    function Test: Boolean; dispid 500;  end;  TTest = class(TInterfacedObject, ITest, IDispatch)  protected    function Test: Boolean; stdcall;    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;//以下是调用var  I: ITest;  Disp: ITestDisp;  V: Variant;begin  //用非disp接口调用, 直接执行到 Test 方法内部  I := TTest.Create;  I.Test;  //用dips接口调用,执行到Invoke,再由 Invoke 执行其它方法  Disp := TTest.Create as ITestDisp;  Disp.Test;  //用Variant调用,首先执行到 GetIDsOfNames 获取方法ID,然后再执行到 Invoke 再由 Invoke 执行其它方法  V := TTest.Create as ITestDisp;  V.Test;end;


我想要的效果正是类似DispID的效果, 既只要有接口就可以调用, 避免传错参数或调错方法,
然而我发现当执行到 Invoke 时传来的只是方法的DispID
于是我无从下手了,不知道该如何把DispID解释成方法名或方法地址,于是无法进行调用实际想调用的方法

跟据我的实验,用Variant的方式,只要在其调用GetIDsOfNames时生成一个模拟的DispID,
这个DispID便可以由Invoke获取了,然而这个DispID却不是接口声明时的DispID,于是
用disp接口仍然无法获取方法地址.

我跟踪过TAutoObject的调用,他的调用是通过工厂类直接执行,然而一直跟踪下去才发现他是调用了Ole32 API,而这个API
是需要IDL Table支持的,即一定要是COM或COM+才能获取到。

用Variant调用的方式确实能满足我的需要,但其不能直接使用接口调用,传错参数也能编译通过,并且效比较低,
首先要执行 GetIDsOfNames获取方法ID,再进行调用。

经过跟踪调试发现,只要引用了ComObj单元,Disp接口调用时,都会调用到ComObj的DispCallByIDProc函数指针,该指针指向
DispCallByID 函数,通过修改这个函数的指针,指向自己的DispCallByID,由DispCallByID转向Invoke以外的另一个方法把
方法名传过去,也能达到我想要的效果,但是这样做是修改了Delphi内部的调用机制,比起
这种方法,我更倾向于使用原有的机制,如果通过通过DispID获取到方法地址那才是最佳解决案。








[解决办法]
高手提的问题,太难了。
我也曾经想过这个问题,不过我的应用仅仅是用别人接口的Invoke,但是没有勇气去解决。 反问一个问题,你上面的代码执行不通耶。第二、第二种调用都执行不过。期望高手为你解决。

[解决办法]
回去研究一下啦
[解决办法]
呵呵,我也来研究研究!
[解决办法]
IDispatch::GetTypeInfo
[解决办法]
哎,都看不懂啊 好麻烦啊
[解决办法]
bu cuo,挺简单的,看看api就能搞定。。

热点排行