使用带有COM接口的STL智能指针
using STL smart pointers with COM interfaces
我正在尝试使用标准的C 库智能指针,该指针使用MS COM用于其大多数功能的库(我必须说我对COM并不熟悉)。因此,我有以下unique_ptr
struct COMDeleter {
template<typename T> void operator()(T* ptr) {
if (ptr) ptr->Release();
}
};
在示例代码中,我们有类似的东西:
class MyClass
{
public:
MyClass(IDeckLink * device)
: m_deckLink(device)
{
}
MyClass::~MyClass()
{
if (m_deckLink != NULL)
{
m_deckLink->Release();
m_deckLink = NULL;
}
}
IDeckLink * m_deckLink;
};
这可以替换为:
class MyClass
{
public:
MyClass(IDeckLink * device)
{
m_deckLink.reset(device);
}
std::unique_ptr<IDeckLink, COMDeleter> m_deckLink;
};
现在,我有另一个称为 IDeckLinkInput
的接口,我想以类似的方式包装,但是初始化的方式与以下方式不同:
IDeckLinkInput* m_deckLinkInput = NULL;
if (m_deckLink->QueryInterface(IID_IDeckLinkInput, (void**) &m_deckLinkInput) != S_OK)
return false;
所以,如果我有一个智能排列,则是:
std::unique_ptr<IDeckLinkInput, COMDeleter> m_deckLinkInput(nullptr);
我不确定如何像上面的初始化函数一起使用它?它甚至可以做到吗?还是我应该坚持使用旧样式C ?
类似的东西:
template<class U, class T>
std::unique_ptr<U, COMDeleter>
upComInterface( GUID guid, T const& src ) {
if (!src) return {};
T* r = nullptr;
if (src->QueryInterface( guid, (void**)&r) != S_OK)
return {};
return {r, {}};
}
然后我们:
auto deckLink = upComInterface<IDeckLinkInput>( IID_IDeckLinkInput, deckLink );
这里有一个小的干违规行为 - 每次执行此操作时,必须重复IDeckLinkInput
和IID_IDeckLinkInput
之间的链接,并弄错了它会导致行为不确定。
我们可以通过多种机制来解决此问题。就个人而言,我会选择标签调度类型:
namespace MyComHelpers {
template<class T> struct com_tag_t {using type=T; constexpr com_tag_t(){};};
template<class T> constexpr com_tag_t<T> com_tag{};
template<class T>
constexpr void get_com_guid( com_tag_t<T> ) = delete; // overload this for your particular types
template<class T>
constexpr GUID interface_guid = get_com_guid( com_tag<T> );
}
现在我们可以将类型与GUID相关联。在IDeckLinkInput
的名称空间中,这样做:
constexpr GUID get_com_guid( MyComHelpers::com_tag_t<IDeckLinkInput> ) {
// constexpr code that returns the GUID
}
然后,我们重写GET接口函数:
std::unique_ptr<U, COMDeleter>
com_cast( T const& src ) {
if (!src) return {};
T* r = nullptr;
if (src->QueryInterface( MyComHelpers::interface_guid<T>, (void**)&r) != S_OK)
return {};
return {r, {}};
}
和使用变为:
auto declLink = com_cast<IDeckLinkInput>(m_deckLinkInput);
有很多方法可以将类型与GUID相关联,包括特征类。constexpr
基于ADL的查找功能和可变模板只是一种方式。
代码未测试。
相关文章:
- 1d 智能指针不适用于语法 (*)++
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 优先顺序:智能指针和类析构函数
- 在C应用程序中运行C++(带有STL)函数
- 使用2个键的cpp-stl::优先级队列排序不正确
- 对于C++中使用智能指针的指针算术限制,有没有一种变通方法
- 在STL容器中使用模板类
- 智能指针作为无序映射键,并通过引用进行比较
- 用C++中的CPerson(类)类型的对象初始化STL矢量
- 将stl字符串缩小到小于15个字符的容量
- 智能指针概念所有权和寿命
- 在为LINUX创建共享库时,如何避免STL的私有/弱副本
- 检查函数返回类型是否与STL容器类型值相同
- 删除包含包含动态对象的 STL 容器的智能指针
- 如何避免自定义 STL 向量类的智能指针 delete[] 异常?
- 使用带有COM接口的STL智能指针
- STL数据结构中的智能指针的用例
- STL 容器是否像shared_ptr一样执行智能释放
- 在STL容器中放置智能指针