佚名通过本文主要向大家介绍了dispid,c dispid,dispid newwindow3,delphi 接口,delphi 支付宝接口等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
问题: Delphi 如何通过接口方法的DispID获取方法名称?
描述:
我想要的效果正是类似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获取到方法地址那才是最佳解决案。
解决方案1:
描述:
VC区也发一个
最近研究了Delphi RTTI
想要实现一个类似TAutoObject功能的类
经过以下试验分析
Delphi 的双重接口的调用模式大致如下
//接口
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获取到方法地址那才是最佳解决案。
解决方案1:
GetTypeInfo呢
解决方案2: 给楼主一个和这个类似的东西:
http://blog.csdn.net/fengrx/archive/2009/03/29/4033206.aspx
您可能想查找下面的文章:
- 请问怎样在DISPID_AMBIENT_DLCONTROL中实现下载控制?
- 在DISPID_BEFORENAVIGATE2事件中如何判断是否为IFRAME事件?
- 请教各位,如何修改控件暴露的接口方法的dispid,具体描述见内。
- 想截取鼠标在IE工作区左键点击事件,可是每次都截取到超过5次DISPID_HTMLELEMENTEVENTS_ONCLICK事件
- DISPID起什么作用?
- 获取IE弹出窗口的问题(DISPID_NEWWINDOW2)
- 还有的DISPID叫啥名字呢?
- DISPID_BEFORENAVIGATE2事件
- 关于DISPID_ONADDRESSBAR
- 编译的时候说:DISPID_BEFORENAVIGATE2没有定义