【问题标题】:C++ COM+ method argument deductionC++ COM+ 方法参数推导
【发布时间】:2018-02-07 19:18:28
【问题描述】:

我在学习 C++ 模板元编程的过程中遇到了一些麻烦。我正在尝试创建一些 COM+ 包装器,这样我将它们与 C++ 混合在一起的生活会变得更快乐:)

我的第一步是创建一个通过Release 方法管理COM+ 对象的智能指针:

template <typename COM>
using com_ptr = std::shared_ptr<COM>;

template<class COM>
com_ptr<COM> make_com_ptr(COM **ppv)
{
    auto ret = com_ptr<COM>(*ppv, [](COM *p) { if (p) p->Release(); });
    *ppv = NULL;
    return ret;
}

到目前为止一切顺利,现在是棘手的问题。 (几乎)所有返回另一个 COM+ 对象的 COM+ 方法都将返回上述接口作为指向方法参数列表指针的指针,例如 HRESULT WINAPI IXMLDOMDocument::selectSingleNode(BSTR, IXMLDOMNode**)

我想/需要调用一些(成员)函数,它可以给我结果指针作为它的返回值,像这样:

IXMLDOMDocument *prawDoc(nullptr);
CoCreateInstance(..., reinterpret_cast<LPVOID*>(&prawDoc));
auto pDoc = make_com_ptr(&prawDoc);
com_ptr<IXMLDOMNode> pNode = FX(pDoc, &IXMLDOMDocument::selectSingleNode,_bstr_t("//xpath"));
^^(auto pNode = ...)         ^^ (the function)

现在,我已经得到了什么:

template<typename COMRET, typename COM, typename METHOD, typename A1>
com_ptr<COMRET> _prv_com_comret(com_ptr<COM> This, const METHOD &Method, A1 Arg1)
{
    COMRET *ppv(nullptr);
    ::SetLastError((*This.*Method)(Arg1, &ppv));
    return make_com_ptr(&ppv);
}

#define com_comret( COM, This, Method, ... )\
    _prv_com_comret<COM>( This, &decltype(This)::_Ptr_base::element_type::Method, __VA_ARGS__ )

所以,有了这个模板函数和宏,我可以写这样的东西:

auto pNode = com_comret(IXMLDOMNode, pDoc, selectSingleNode, _bstr_t("//xpath"));

这个解决方案困扰我的是,我必须指定返回类型 (IXMLDOMNode),即使编译器知道它的类型(每个人都会同意,它是IXMLDOMDocument::selectSingleNode方法)

所以,最后,这篇长篇文章被简化为:是否可以使用某种模板元编程+宏巫术来推断该参数类型而无需指定它?

提前致谢!!

【问题讨论】:

  • 仅供参考,这没关系。对于生产代码,从 IDL 或类型库生成的代码开始。
  • 使用 IDL 生成的代码是什么意思?

标签: c++ winapi template-meta-programming com+


【解决方案1】:

打开指向成员的指针类型而不是使其不透明。

template<typename COMRET, typename COM, typename A1>
com_ptr<COMRET> _prv_com_comret(com_ptr<COM> This, COMRET (COM::* const Method)(A1, COMRET**), A1 Arg1)

这应该可以在没有明确指定模板参数的情况下调用。

【讨论】:

  • 谢谢本!我设法通过您的回复解决了我的问题!
猜你喜欢
  • 1970-01-01
  • 2021-06-16
  • 2015-12-07
  • 2021-08-31
  • 1970-01-01
  • 2021-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多