CreateStdDispatch如何知道调用什么方法? [英] How does CreateStdDispatch know what method to invoke?

查看:304
本文介绍了CreateStdDispatch如何知道调用什么方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我面临着实施 IDispatch 界面。有四种方法,幸运的是其中3个很容易:

  function TIEEventsSink.GetTypeInfoCount(...):HResult; 
{
结果:= E_NOTIMPL;
}

function TIEEventsSink.GetTypeInfo(...):HResult;
{
结果:= E_NOTIMPL;
}

function TIEEventsSink.GetIDsOfNames(...):HResult;
{
结果:= E_NOTIMPL;
}

这是最后一个方法, Invoke 这很难。在这里,我面临着实际情况下的 DispID ,并调用我适当的方法;

 函数Invoke(
dispIdMember:DISPID;
riid:REFIID;
lcid:LCID;
wFlags:WORD;
var pDispParams:DISPPARAMS;
var pVarResult:VARIANT;
var pExcepInfo:EXCEPINFO;
var puArgErr: DWORD
):HRESULT;

不想写所有繁琐的样板代码,我肯定会有错误,我去了Google搜索,而不是做任何工作。



我在 IDispatch.Invoke 的MSDN文档:



< >

一般来说,您不应直接实现调用


优秀!我不想实现它!继续阅读:


而是使用dispatch接口创建函数 CreateStdDispatch DispInvoke 。有关详细信息,请参阅 CreateStdDispatch DispInvoke 创建IDispatch界面公开ActiveX对象


创建IDispatch接口链接说:


通过以下任何方式:




  • [snip]

  • 调用 CreateStdDispatch 函数。这种方法是最简单的,但它不提供丰富的错误处理或多种国家语言。

  • [snip]


优异, CreateStdDispatch 它是:


通过单个函数调用创建IDispatch接口的标准实现。

  HRESULT CreateStdDispatch(
IUnknown FAR * punkOuter,
void FAR * pvThis,
ITypeInfo FAR * ptinfo,
IUnknown FAR * FAR * ppunkStdDisp
);


我打算叫做:



CreateStdDispatch(
myUnk,//指向对象的IUnknown实现的指针
anotherObject,//指向要暴露的对象的指针。
nil //描述暴露对象的类型信息的指针(我没有类型信息)
dispInterface //为我实现IDispatch的对象的IUnknown
);

我无法弄清楚Windows API如何实现 CreateStdDispatch 知道对我的对象调用什么方法 - 特别是因为 CreateStdDispatch 不知道我使用的面向对象语言,或者它的调用约定。 / p>

如何 CreateStdDispatch 知道




  • 调用给定 dispid

  • 我的语言的调用约定的方法是什么?

  • 如何处理我的面向对象的语言写的异常?



>:我别无选择,只能实现 dispinterface ;我没有定义界面 。我希望它是一个简单的早期绑定 IUnknown ,但它tisn't。

解决方案

ITypeInfo 参数传递到 CreateStdDispatch 中是否公开了所有方法信息?



所以你可以创建类型信息,先调用 CreateDispTypeInfo ,然后传递给 CreateStdDispatch 需要 INTERFACEDATA >其中包含所有这些信息



我可能是错误的,因为我没有时间来研究它,但这对我有意义。
我稍后调查这个问题,并更新答案。


i'm faced with implementing an IDispatch interface. There are four methods, and fortunately 3 of them are easy:

function TIEEventsSink.GetTypeInfoCount(...): HResult;
{
   Result := E_NOTIMPL;
}

function TIEEventsSink.GetTypeInfo(...): HResult;
{
   Result := E_NOTIMPL;
}

function TIEEventsSink.GetIDsOfNames(...): HResult;
{
   Result := E_NOTIMPL;
}

It's the last method, Invoke that is difficult. Here i am faced with having to actually case the DispID, and call my appropriate method; unmarhsalling parameters from a variant array.

function Invoke(  
  dispIdMember: DISPID;
  riid: REFIID;
  lcid: LCID;
  wFlags: WORD;
  var pDispParams: DISPPARAMS;
  var pVarResult: VARIANT;
  var pExcepInfo: EXCEPINFO;
  var puArgErr: DWORD
): HRESULT;

Not wanting to have to write all the tedious boilerplate code, that i'm sure will have bugs, i went googling - rather than doing any work.

i found this snippit on the MSDN Documentation of IDispatch.Invoke:

Generally, you should not implement Invoke directly.

Excellent! i didn't want to implement it anyway! Continuing reading:

Instead, use the dispatch interface to create functions CreateStdDispatch and DispInvoke. For details, refer to CreateStdDispatch, DispInvoke, Creating the IDispatch Interface and Exposing ActiveX Objects.

The Creating the IDispatch Interface link says:

You can implement IDispatch by any of the following means:

  • [snip]
  • Calling the CreateStdDispatch function. This approach is the simplest, but it does not provide for rich error handling or multiple national languages.
  • [snip]

Excellent, CreateStdDispatch it is:

Creates a standard implementation of the IDispatch interface through a single function call. This simplifies exposing objects through Automation.

HRESULT CreateStdDispatch(  
  IUnknown FAR*  punkOuter,        
  void FAR*  pvThis,               
  ITypeInfo FAR*  ptinfo,          
  IUnknown FAR* FAR* ppunkStdDisp  
);

i was going to call it as:

CreateStdDispatch(
    myUnk,          //Pointer to the object's IUnknown implementation.
    anotherObject,  //Pointer to the object to expose.
    nil             //Pointer to the type information that describes the exposed object (i has no type info)
    dispInterface   //the IUnknown of the object that implements IDispatch for me
);

What i cannot figure out is how the Windows API implemention of CreateStdDispatch knows what methods to call on my object - especially since CreateStdDispatch doesn't know what object-oriented language i'm using, or its calling conventions.

How will CreateStdDispatch know

  • what method to call for a given dispid?
  • the calling convention of my language?
  • how to handle exceptions from the language that my object oriented object is written in?

Note: i have no choice but to implement a dispinterface; i didn't define the interface. i wish it was a simple early bound IUnknown, but it tisn't.

解决方案

Doesn't the ITypeInfo parameter passed into CreateStdDispatch expose all of the method information?

So you'd create type info first calling CreateDispTypeInfo and pass that through to CreateStdDispatch which can then use the type information to work out which method to call since CreateDispTypeInfo requires INTERFACEDATA which contains all this information

I could be way wrong since I don't have time to look into it but that would make sense to me. I'll investigate this later and update the answer.

这篇关于CreateStdDispatch如何知道调用什么方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆