Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;用于访问COM对象属性的包装函数(宏)_C++_Properties_Com_Macros - Fatal编程技术网

C++ C++;用于访问COM对象属性的包装函数(宏)

C++ C++;用于访问COM对象属性的包装函数(宏),c++,properties,com,macros,C++,Properties,Com,Macros,我有一个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 obj

我有一个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));
这个块不太长,但是当使用了很多属性时,代码就不那么好看了。有没有办法将属性访问代码分离到某个宏或模板函数中,以便能够直接使用属性,如下所示:

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;
}
我仍在寻找一种方法来消除通话中的“IInterfaceName::”部分

(正如汉斯已经在评论中所说的。真的。我发现C++中的COM不可忍受)< /P> 在默认设置中,这将生成一个高级包装器。像您的示例这样的属性是通过编译器特定的扩展来公开的:

LONG lValue = pInterface->Width;

[编辑]更多信息:

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

使用默认的#导入设置:

  • 你可以得到高水平的包装
    • 将失败(hr)转换为
      \u com\u错误
      异常
    • [out,retval]
      转换为实际返回值
    • 将属性作为属性公开
    • 通过
      raw\u方法()
      get\u属性()
      等访问“原始”COM接口
  • GUID可通过
    \uuuIdof()
    获得,例如
    \uuuIdof(IMyInterface)
    而不是
    IID\u IMyInterface
  • 所有否认都位于基于COM库名称的命名空间中
但是,所有这些都可以通过#导入属性进行配置


我将.idl放在一个单独的项目中,只生成.tlb,并且我使用#导入的头来实现和使用接口。这意味着您必须对向导生成的代码进行soem调整,例如使用
raw

作为COM方法实现的前缀查看#import指令,它会从类型库自动生成包装器。这很有趣,在某些情况下可能会有所帮助,但据我所知,若属性getter失败,编译器将生成一个异常。在我们的公司代码中,例外是不受欢迎的:(这真的很令人伤心。我可以看到(一些孤立的)避免例外的原因,但更多的时候,这种方法是错误的。--“舒适的”包装器需要某种机制来指示失败,在这种情况下,除了异常之外,我看不到任何合理的情况。--您可以诱使生成的代码调用回调,但是除了终止程序之外,还会发生什么呢?