不情愿地通过 RPC 调用 QueryInterface
Unwillingly calling QueryInterface via RPC
在我的应用程序中,我创建了一个对象 A,该对象通过 CreateInstance
创建一个对象 B。 这两个对象应位于同一进程中。
现在我看到对象 B 在被要求提供某个接口时返回E_NOINTERFACE,尽管我在COM_MAP中定义了它:
class B:
{
// ....
BEGIN_COM_MAP(B)
COM_INTERFACE_ENTRY(IB)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IXXX) // the interface I'm interested in
END_COM_MAP()
// .....
};
和 A 代码:
#define FORWARD_ERROR( expr ) { hr=expr; if( !SUCCEEDED( hr ) ) return hr;}
IBPtr b;
FORWARD_ERROR( b.CreateInstance( __uuidof( B ), 0, CLSCTX_INPROC_SERVER ) );
IXXXPtr x;
HRESULT hrIf = b.QueryInterface( __uuidof( IXXX ), x );
// ===> now x is NULL, and hrIf contains E_NOINTERFACE
当我调试它并在COM_MAP中放置断点时,我在最低帧中看不到我的源代码,而是一些 ole32.dll 的CRpcThread::WorkerLoop
。
我不知道我如何指出应该通过 OLE 和 RPC 调用QueryInterface
。 有什么想法吗?
从你的描述来看,这绝对是编组开始了。编组是通过RPC隧道调用来完成的,所以它看起来很奇怪,但这就是在Windows上完成的方式。
消费者线程可能用COINIT_APARTMENTTHREADED
调用CoInitializeEx()
。由于要创建的对象被标记为Free
因此不可能在调用方的公寓中创建(请参阅有关公寓的非常好的解释)。相反,COM 试图打开编组,您可能没有任何促进编组的东西,在这种情况下CoCreateInstance()
返回E_NOINTERFACE
因为 COM 内部工作请求一堆用于封送的接口,一旦所有这些请求失败,它最终会得到E_NOINTERFACE
并返回它,这当然对您来说根本不方便。
然后你从Free
更改为Both
这意味着"Apartment
COM 认为合适的Free
"COM 被正式允许将对象放入与调用方相同的公寓中,并且不需要编组,因此您不再看到那个看起来很奇怪的错误代码。
B
类的线程模型是"Free",而我正在从多线程上下文中创建对象。 将B
切换到"两者"解决了这个问题。
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 函数调用中参数的顺序重要吗
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在c++类上调用void函数
- 为什么 std::unique 不调用 std::sort?
- 调用专用模板时出错"no matching function for call to [...]"
- 选择要调用的构造函数
- C++为什么尽管我调用了void函数,它却不起作用
- 构造函数正在调用一个使用当前类类型的函数
- 变量没有改变?通过向量的函数调用
- 没有为自己的结构调用列表推回方法
- 调用'begin(int [n])'没有匹配函数
- 什么时候调用析构函数
- 如何用参数值调用函数(仅在运行时已知)
- std::cout.imbue()多重调用
- 函数何时会在c++中包含stack_Unwind_Resume调用