没有实现ATL COM的IDispatch [英] Implement COM IDispatch without ATL

查看:267
本文介绍了没有实现ATL COM的IDispatch的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写一个Excel RTD服务器的实现,我被困在样板的组件类,它实现的IDispatch 。我有ATL进不去,但我使用的ActiveQt,虽然我很感兴趣的是如何做到这一点的原始C或C ++了。如何正确地实施在COM服务器的IDispatch 的方法呢?

I am writing an Excel RTD server implementation and I'm stuck on the boilerplate for a coclass which implements IDispatch. I have no access to ATL, but I am using ActiveQt, although I'm interested in how to do this in raw C or C++ too. How to properly implement the IDispatch methods in a COM server?

该文件只是panickingly可怕,一如既往。我至今读:

The documentation is just panickingly awful, as always. What I have so far read:


  • 这是更好的做法是委托的IDispatch 方法调用一些的ITypeInfo 。这是正确的?

  • 如果是这样,如何​​得到一个的ITypeInfo 来自己? <一href=\"http://msdn.microsoft.com/en-us/library/windows/desktop/ms221027%28v=vs.85%29.aspx\">LoadTypeLib()和家人(随后通过查看的ITypeLib :: GetTypeInfo的())?

  • 如果不是,它是如何实现正常吗?链接高质量的文档和自成一体的例子有多大用处的。

  • It is better practice to delegate the IDispatch method calls to some ITypeInfo. Is this correct?
  • If so, how to get an ITypeInfo to myself? LoadTypeLib() and family (followed by looking at ITypeLib::GetTypeInfo())?
  • If not, how is it implemented properly? Links to good-quality documentation and self-contained examples are of much use.

LoadTypeLib()办法似乎是适当的COM的客户的到达类型信息对于某些库,而不是一个COM服务器试图反思本身。我是不是正确的?

The LoadTypeLib() approach seems appropriate for a COM client to reach type information for some library, not for a COM server trying to introspect itself. Am I correct?

推荐答案

如果该接口在IDL通过正确定义并编译成类型库,实施的IDispatch 类型库的的ITypeInfo 是因为它主要是委托十分可行的。有趣的是的ITypeInfo ::它依靠正确的C ++ v表布局调用

If the interface is properly defined in the IDL and compiled into a type library, implementing IDispatch via the type library's ITypeInfo is quite feasible as it's mostly delegating. The interesting part is ITypeInfo::Invoke which relies upon correct C++ v-table layout:

public class CComClass: public IDualInterface
{
    // ...

    // implementing IDualInterface

    ITypeInfo* m_pTypeInfo // can be obtained via ITypeLib::GetTypeInfoOfGuid for the GUID of IDualInterface

    // IDispatch
    STDMETHODIMP GetTypeInfoCount(UINT* pctinfo)
    {
        *pctinfo = 1;
        return S_OK;
    }

    STDMETHODIMP GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)
    {
        if (0 != itinfo)
            return E_INVALIDARG;
        (*pptinfo = m_pTypeInfo)->AddRef();
        return S_OK;
    }

    STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid)
    {
        return m_pTypeInfo->GetIDsOfNames(rgszNames, cNames, rgdispid);
    }

    STDMETHODIMP Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr)
    {
        return m_pTypeInfo->Invoke(static_cast<IDualInterface*>(this), dispidMember, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr); 
    }
}

我已经用类似的方法来创建为MSHTML DOM脚本,调用包装对象绕过脚本安全限制

所以,你从哪里得到的ITypeInfo?从本质上讲,你用得到它:

So where do you get the ITypeInfo from? Essentially you get it by:


  1. 写它声明的接口作为接口的IDL文件。它是一个双接口,因为这是的ITypeInfo 的实施是如何知道哪个函数调用 - 它不能只是直接调用你的类C ++的功能,因为C ++有没有反思因为它是语言无关。因此,它只能委托调用调用在类型库中声明的另一种方法。

  2. 编译IDL到一个头文件,并键入库作为构建过程的一部分

  3. 从IDL生成的头文件定义了接口,你的实现类必须继承。一旦你已经实现了所有的方法,你是好去。 (为了使它们全部回归发展启动 E_NOTIMPL 然后实现逐一)

  4. 安装类型库,要么到目标目录,或如EXE / DLL的资源。这就需要通过调用 RegisterTypeLib 注册。如果是作为资源嵌入,你应该从你的中的DllRegisterServer 执行调用它。

  5. 加载类型库时创建的对象的第一个实例,使用 LoadTypeLib 。这给你一个的ITypeLib

  6. 得到你所需要使用的ITypeInfo 的GetTypeInfoOfGuid

  1. Write an IDL file which declares your interface as a dual interface. It has to be a dual interface, as that is how the ITypeInfo implementation knows which function to invoke - it cannot just invoke the C++ functions directly on your class because C++ has no reflection and because it is language neutral. Therefore it can only delegate the Invoke call to another method declared in the type library.
  2. Compile the IDL to a header file and type library as part of the build process
  3. The header file produced from the IDL defines the interface, which your implementing class must inherit from. Once you have implemented all the methods you are good to go. (For development start by making them all return E_NOTIMPL then implement them one by one)
  4. Install the Type Library, either to the destination directory, or as a resource in the EXE/DLL. It will need to be registered by calling RegisterTypeLib. If it is embedded as a resource, you should call this from your DllRegisterServer implementation.
  5. Load the type library when the first instance of your object is created, using LoadTypeLib. This gives you an ITypeLib
  6. Get the ITypeInfo you need using GetTypeInfoOfGuid.

这篇关于没有实现ATL COM的IDispatch的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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