没有实现ATL COM的IDispatch [英] Implement COM IDispatch without ATL
问题描述
我写一个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 someITypeInfo
. Is this correct? - If so, how to get an
ITypeInfo
to myself? LoadTypeLib() and family (followed by looking atITypeLib::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:
- 写它声明的接口作为双接口的IDL文件。它是一个双接口,因为这是
的ITypeInfo
的实施是如何知道哪个函数调用 - 它不能只是直接调用你的类C ++的功能,因为C ++有没有反思因为它是语言无关。因此,它只能委托调用
调用在类型库中声明的另一种方法。 - 编译IDL到一个头文件,并键入库作为构建过程的一部分
- 从IDL生成的头文件定义了接口,你的实现类必须继承。一旦你已经实现了所有的方法,你是好去。 (为了使它们全部回归发展启动
E_NOTIMPL
然后实现逐一) - 安装类型库,要么到目标目录,或如EXE / DLL的资源。这就需要通过调用
RegisterTypeLib
注册。如果是作为资源嵌入,你应该从你的中的DllRegisterServer
执行调用它。 - 加载类型库时创建的对象的第一个实例,使用
LoadTypeLib
。这给你一个的ITypeLib
- 得到你所需要使用的ITypeInfo
的GetTypeInfoOfGuid
。
- 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 theInvoke
call to another method declared in the type library. - Compile the IDL to a header file and type library as part of the build process
- 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) - 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 yourDllRegisterServer
implementation. - Load the type library when the first instance of your object is created, using
LoadTypeLib
. This gives you anITypeLib
- Get the ITypeInfo you need using
GetTypeInfoOfGuid
.
这篇关于没有实现ATL COM的IDispatch的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!