我有一个C#程序集,它完成一些工作,并将工作结果发送回C++核心。我试图使用反射来传递它,因为C#程序集运行在一个不同于它从C++内核初始化的线程上。我尝试过使用COM接口作为参数类型。
IDL:
HRESULT SendEvent([in] IEventData *pEventData);C#:
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:
HRESULT SendEvent([in] IDispatch *pEventData);C++:
STDMETHODIMP CInspectionCore::SendEvent(IDispatch *pEventData)
{
IEventData *pIEventData = (IEventData *)pEventData;即使调用pIEventData->GetIDsOfNames()也失败。
当从不同的C#线程调用C#对象时,是否有方法将在C#中创建的COM对象传递给C++?
发布于 2022-04-07 06:38:38
对于COM,您应该永远不要将COM接口强制转换到另一个COM接口中,如下所示:
STDMETHODIMP CInspectionCore::SendEvent(IDispatch *pEventData)
{
IEventData *pIEventData = (IEventData *)pEventData; // wrong!
}相反,必须使用QueryInterface,这很好:
STDMETHODIMP CInspectionCore::SendEvent(IDispatch *pEventData)
{
IEventData* pIEventData;
HRESULT hr = pEventData->QueryInterface(&pIEventData);
if (FAILED(hr)) // etc.
}在某些情况下(实际上经常),生铸可能会产生错误的印象,认为它是好的。
在您的例子中,它不能工作,因为您使用不同的线程来创建隐式代理(公寓等)。您可以看到,如果SendEvent中的断点在调用时查看调用堆栈,则都是COM封送处理。
https://stackoverflow.com/questions/71754032
复制相似问题