检查 COM 指针是否存在
Check existence of COM pointer
在 c++ 中,MFC:
我有一个CComPointer:
CComPointer<IMyTask> m_pTask;
我的代码中有很多地方,我调用此 ComPointer 来运行任务的方法。例如:
void method1()
{
if (FAILED(hRet = m_pTask->MyFunc1()))
.....
}
void method2()
{
if (FAILED(hRet = m_pTask->MyFunc2()))
.....
}
我尝试解决一个问题,以便在MyTask关闭时恢复。我写了一个方法,recover(),将CoCreate重新运行到MyTask,它实际上解决了这个问题。
我可以看到,如果MyTask死了,我得到的HR失败代码为-2147023174,RPC服务器不可用。但是,com 指针m_pTask具有完整的数据(它不知道任务已死)。
我可以做这样的事情:
void method1()
{
if (FAILED(hRet = m_pTask->MyFunc1()))
if (hRet == -2147023174)
recover();
.....
}
void method2()
{
if (FAILED(hRet = m_pTask->MyFunc2()))
if (hRet == -2147023174)
recover();
.....
}
但是,因为我通过指针对方法有很多调用,所以我想做一些更通用的东西。我希望每次尝试通过 ComPointer 运行方法时,在运行该方法之前,检查任务是否已存在,如果没有 - 运行恢复方法。因为即使任务已死,ComPointer 仍然拥有 CoCreate 时间的所有数据,我不知道该怎么做。
我该怎么做?
由于系统中发生的错误,该任务已死亡,目前我的解决方案不需要找到任务失败的原因,只需恢复它即可。我正在寻找一个通用的解决方案 - 比如 ComPointer 的包装器,但我希望包装器类只检查 MyTask 是否仍然存在,如果是 - 它将返回 ComPointer,如果没有,它将运行恢复。
我该怎么做?
好的,这是一个一般性问题的一般性答案。我不想知道,为什么任务实际上是死的,而指针不是。为任务指针编写一个包装器并改用它。它将看起来像这样:
class CMyTaskWrapper
{
CComPtr<IMyTask> m_ptr;
...
HRESULT myFunc1()
{
HRESULT hRes = m_ptr->myFunc1();
if(hRes == 0x800706BA)
{
recover();
}
return hRes;
}
... //here you should list all members of IMyTask
};
编辑1:添加了一个宏示例(请参阅注释#2)
MYMACRO_0(HRESULT_GETTER, POINTER, FUNCTION)
HRESULT_GETTER = POINTER->FUNCTION();
if(HRESULT_GETTER == 0x800706BA) recover();
HRESULT_GETTER = POINTER->FUNCTION()
MYMACRO_1(HRESULT_GETTER, POINTER, FUNCTION, PARAM1)
HRESULT_GETTER = POINTER->FUNCTION(PARAM1);
if(HRESULT_GETTER == 0x800706BA) recover();
HRESULT_GETTER = POINTER->FUNCTION(PARAM1)
//here you should add MYMACRO_2 ... MYMACRO_N
您可以通过以下方式使用它:
MYMACRO_0(hRes, m_pTask, MyFunc1);
MYMACRO_1(hRes, m_pTask, MyFunc2, parameter_to_pass);
这可能会有所帮助,这将隐藏函数列表,但尽管如此,使用这样的代码并不是一个好主意。
CComPointer 的实现相当简单。 您可以轻松地剪切和粘贴它以形成您自己的智能指针类的基础。
CComPointer 实现依赖于重写"->"运算符。 这避免了了解接口提供哪些方法的需要。 每个呼叫都会被有效地拦截,然后被转发。
在新的智能指针类中,您可以构建所需的额外功能来实现"->"运算符重写。
进行哪些检查来验证呼叫更难。
我认为 QueryInterface是一个有效的调用,您可以使用它来检查连接是否处于活动状态 - QueryInterface 保证存在,并且需要调用到真正的实现。
但是,总会存在争用条件 - 检查呼叫和实际呼叫之间的连接可能会失败。
因此,您可能最好只是进行真正的调用,如果失败,请尝试恢复并再次调用 - 这在一个很好的模式中很难做到 - 可能最容易实现的宏参见Forgottn的答案。
听起来你想要一个自定义的DCOM代理,而不是midl和Windows提供的默认逻辑。 这是可能的,但这也是很多工作。 如果需要向使用 COM 创建对象的第三方代码提供自定义行为,这是最佳选择。
当您控制客户端代码时,编写一个实现相同 COM 接口的包装类可能会更简单,并且通过将每个调用转发到远程服务器来实现。
MFC 类向导允许您围绕 com 组件生成包装类。本页介绍了如何操作。
生成包装类后 - 您可以编辑任何方法以在其中实现重试逻辑。您可以对 #import 指令生成的包装类使用相同的方法。
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 有了gcc,是否可以链接库,但前提是它存在
- gcc和clang在表达式是否为常量求值的问题上存在分歧
- 如何检查QList中是否存在值
- 根据某个函数是否存在启用模板
- 地图计数确实很重要,或者只是检查是否存在
- C++中是否存在 std::conditional 的懒惰等价物?
- 无论如何,我可以确定构造函数是否存在吗?
- COM :是否可以查看是否存在对我的某个 COM 对象的进程外引用?我可以释放它吗?
- 堆分配的对象是否存在永不为空的唯一所有者?
- 扩展类中的可选 vir 函数,测试它在运行时是否存在
- 模板化检查是否存在带有参数列表的类成员函数?
- 是否存在包含负号的isdigit函数(过载)
- 如何巧妙地编写两个函数——一个用于检查是否存在解决方案,另一个用于获取所有解决方案
- 检查编译时是否存在静态函数
- 向量是否存在行主要形式?
- 检查 TinyXML 中的元素是否存在
- 检测是否存在具有 C++17 的类成员
- 虚拟继承中是否存在多重继承?
- 我遇到了这个代码片段,不明白. 它递归检查 C++ 字符串中是否存在大写字符