您现在的位置:首页 >> API >> API >> 内容

Variant调用的接口必须是由IDispatch接口继承问题

时间:2011/9/3 15:44:27 点击:

  核心提示:现在逐步解析一下,避免以后大家出现我一样的问题。所有的通过Variant调用接口都会通过IDispatch的GetIDsOfNames,通过名字来获取ID(至于怎么通过名字来访问,因为编译器为接口中的...
现在逐步解析一下,避免以后大家出现我一样的问题。
所有的通过Variant调用接口都会通过IDispatch的GetIDsOfNames,通过名字来获取ID(至于怎么通过名字来访问,因为编译器为接口中的每个方法生成一个静态的TCallDesc结果,如果你知道某个方法的TCallDesc结构地址,你可以通过这行代码就知道显示的是什么了,ShowMessage(pchar(@PCallDesc($4873f4)^.ArgTypes[1]));),然后通过ID来调用Invoke方法。在delphi内部有一个包装过程,最后通过的是Variant单元的_DispInvoke方法来转发这个过程,下面是_DispInvoke的核心代码:
if Assigned(VarDispProc) then
    VarDispProc(PVariant(LDestPtr), Variant(Source), CallDesc, @Params);
VarDispProc是一个全局的函数指针,在单元初始化的时候是一个错误函数接口赋值给它(这个错误的字符串信息就是臭名昭著的"Variant method calls not supported")。VarDispProc := @_DispInvokeError;开始我以为真正的代码是由delphi编译器自动加入的,毕竟见得太多类似的“魔法”了:-) 但后来发现自己的接口连脚本也运行不了,最后只得在delphi的Source里面搜索VarDispProc了(这里我推荐大家使用“百度硬盘搜索”,真是太方便了),马上发现了端倪:在ComObj单元的初始化中有这么一句:VarDispProc := @VarDispInvoke;
再看看VarDispInvoke代码,正是真正的派发函数:-) ,在开发的接口单元uses部分加入ComObj,完全OK了,后来自己觉得不爽,写了一个函数,在没有引用ComObj单元的情况下发现也可以很好的运行了o(∩_∩)o...。
下面是我自己实现的一个简单的派发接口,在一般情况下也够用了:-)
procedure MyDispatch(Dest: PVariant; const Source: Variant;
      CallDesc: PCallDesc; Params: Pointer); cdecl;
var
 IDisp:IDispatch;
 pDispid,wcharlen:integer;
 pwc:pwidechar;
 pc:pchar;
begin
  if TVarData(Source).VType=varDispatch then
  begin
    IDisp:=IDispatch(TVarData(Source).VDispatch);
    pc:=pchar(@callDesc^.ArgTypes[callDesc^.ArgCount]);
    wcharlen:=MultiByteToWideChar(0,0,pc,strlen(pc),nil,0);
    pwc:=allocMem(wcharlen*2+2);
    MultiByteToWideChar(0,0,pc,strlen(pc),pwc,wcharlen);
    IDisp.GetIDsOfNames(GUID_NULL,pointer(@pwc),calldesc^.NamedArgCount,0,@pDispid);
    FreeMem(pwc);
    IDisp.Invoke(pDispid,GUID_NULL,0,0,Params,nil,nil,nil);
  end
  else
    raise exception.Create('Variant method calls not supported');//我也发出这个语句:-)
end;
在初始化和终止化的时候替换原来的地址就可以了,
initialization
  Old:=Variants.VarDispProc;
  Variants.VarDispProc:=@MyDispatch;
finalization
  Variants.VarDispProc:=Old;
end.
上面代码经过delphi7的测试,没有uses ComObj也可以正常派发接口调用。

作者:网络 来源:转载
共有评论 0相关评论
发表我的评论
  • 大名:
  • 内容:
本类推荐
  • 没有
本类固顶
  • 没有
  • 盒子文章(www.2ccc.com) © 2020 版权所有 All Rights Reserved.
  • 沪ICP备05001939号