首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否可以使用反射将COM对象从C#传递给C++?

是否可以使用反射将COM对象从C#传递给C++?
EN

Stack Overflow用户
提问于 2022-04-05 14:58:25
回答 1查看 112关注 0票数 1

我有一个C#程序集,它完成一些工作,并将工作结果发送回C++核心。我试图使用反射来传递它,因为C#程序集运行在一个不同于它从C++内核初始化的线程上。我尝试过使用COM接口作为参数类型。

IDL:

代码语言:javascript
复制
    HRESULT SendEvent([in] IEventData *pEventData);

C#:

代码语言:javascript
复制
    WECOInspectionCoreIDL.IEventData eventData = new EventData() as WECOInspectionCoreIDL.IEventData;
    var parameters = new object[1];
    parameters[0] = eventData;
    _piInspectionCore.GetType().InvokeMember("SendEvent", BindingFlags.InvokeMethod, null, _piInspectionCore, parameters);

这将获得atlcom.h hRes =m_pInfo->Invoke(.)中的错误"0x80020005类型不匹配“。显然,该调用最终被转换为“无法转换类型为'System.__ComObject‘的COM对象.不支持这种接口。

我还尝试将参数设置为IDis补丁*,然后调用C++,但它似乎不是真正的对象。

IDL:

代码语言:javascript
复制
    HRESULT SendEvent([in] IDispatch *pEventData);

C++:

代码语言:javascript
复制
    STDMETHODIMP CInspectionCore::SendEvent(IDispatch *pEventData)
    {
       IEventData *pIEventData = (IEventData *)pEventData;

即使调用pIEventData->GetIDsOfNames()也失败。

当从不同的C#线程调用C#对象时,是否有方法将在C#中创建的COM对象传递给C++?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-07 06:38:38

对于COM,您应该永远不要将COM接口强制转换到另一个COM接口中,如下所示:

代码语言:javascript
复制
STDMETHODIMP CInspectionCore::SendEvent(IDispatch *pEventData)
{
    IEventData *pIEventData = (IEventData *)pEventData; // wrong!
}

相反,必须使用QueryInterface,这很好:

代码语言:javascript
复制
STDMETHODIMP CInspectionCore::SendEvent(IDispatch *pEventData)
{
    IEventData* pIEventData;
    HRESULT hr = pEventData->QueryInterface(&pIEventData);
    if (FAILED(hr)) // etc.
}

在某些情况下(实际上经常),生铸可能会产生错误的印象,认为它是好的。

在您的例子中,它不能工作,因为您使用不同的线程来创建隐式代理(公寓等)。您可以看到,如果SendEvent中的断点在调用时查看调用堆栈,则都是COM封送处理。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71754032

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档