C++包装函数(宏)来访问 COM 对象属性

C++ wrapper function (macro) to access COM object properties

本文关键字:访问 COM 对象 属性 包装 函数 C++      更新时间:2023-10-16

我有一个 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 "myInterface.tlb">

(正如汉斯已经在评论中所说的那样。真。我发现 COM C++无法忍受没有(

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

LONG lValue = pInterface->Width;

[编辑] 更多信息:

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

使用默认 #import 设置:

  • 你会得到高级包装器
    • 将失败(小时(转换为_com_error异常
    • [out, retval]转换为实际返回值,
    • 公开属性,就好像它们是属性一样
    • 通过raw_Method()get_Property()等方式访问"原始"COM接口。
  • GUID 可通过__uuidof()获得,例如 __uuidof(IMyInterface)而不是IID_IMyInterface.
  • 所有终止都位于基于 COM 库名称的命名空间中

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

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