【问题标题】:C++ wrapper function (macro) to access COM object properties用于访问 COM 对象属性的 C++ 包装函数(宏)
【发布时间】:2012-05-07 19:50:15
【问题描述】:

我有一个 COM 对象,其接口包含许多按以下方式定义的属性:

[propget] HRESULT Width([out, retval] LONG *lValue);

要从 C++ 访问此类属性,我需要添加如下代码:

LONG lValue;  
HRESULT hr = pInterface->get_Width(&lValue);  
if (FAILED(hr)) lValue = DEFAULT_VALUE;

这个块不是太长,但是当使用许多属性时,代码变得不太好看。有没有办法将属性访问代码分成一些宏或模板函数以便能够直接使用属性,如下所示:

printf("The width of the object is %d", GET_OBJECT_PROPERTY(pInterace, Width, DEFAULT_VALUE));

UPD:VC2008编译器用于构建项目

UPD:谢谢大家!这是我的解决方案:

template <class interface_type, class property_type>
property_type GetPropertyValue(interface_type* pInterface, HRESULT(STDMETHODCALLTYPE interface_type::*pFunc)(property_type*), property_type DefaultValue = 0)
{
  property_type lValue;

  HRESULT hr = (*pInterface.*pFunc)(&lValue);

  if (FAILED(hr)) 
    lValue = DefaultValue;
  return lValue;
}

可以称为

LONG lVideoStreamCount = GetPropertyValue(pInfo, &IInterfaceName::get_VideoStreamCount);

我仍在寻找一种方法来消除调用中的这个 'IInterfaceName::' 部分。

【问题讨论】:

  • 查看#import 指令,它从类型库中自动生成包装器。

标签: c++ properties com macros


【解决方案1】:

#import "myInterface.tlb"

(正如 Hans 已经加入 cmets 一样。真的。我发现 C++ 中的 COM 无法忍受)

这会生成 - 在默认设置中 - 高级包装器。像您的示例这样的属性通过__decspec(property) 公开,这是一个特定于编译器的扩展:

LONG lValue = pInterface->Width;

[编辑] 更多信息:

为了编译 .idl,我禁用了 MIDL 的 C 标头生成(如果需要,代理/存根生成除外)。

使用默认的#import 设置:

  • 你会得到高级包装器
    • 将 FAILED(hr) 转换为 _com_error 异常
    • [out, retval]变成一个真正的返回值,
    • 像属性一样公开属性
    • 通过raw_Method()get_Property() 等提供对“原始”COM 接口的访问权限。
  • GUID 可通过__uuidof() 获得,例如__uuidof(IMyInterface) 而不是 IID_IMyInterface
  • 所有定义都在基于 COM 库名称的命名空间中

但是,所有这些都可以通过#import 属性进行配置。

我将我的 .idl 放在一个单独的项目中,仅生成 .tlb,我使用 #imported 标头来实现和使用接口。这意味着您必须对向导生成的代码进行一些调整,例如在 COM 方法实现前加上 raw_

【讨论】:

  • 这很有趣,在某些情况下可能会有所帮助,但据我所知,如果属性获取器失败,编译器会生成异常。我们的公司代码不欢迎例外:(
  • 真的很伤心。我可以看到(极少数孤立的)避免异常的原因,但这种方法往往是被误导的。 ——“舒适”的包装器需要某种机制来指示失败,除了那种情况下的例外,我看不到任何合理的东西。 --- 您可以欺骗生成的代码调用回调,但是除了终止程序之外应该发生什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-07
  • 1970-01-01
  • 2010-12-12
相关资源
最近更新 更多