对于HRESULT的返回值一般不能直接用比较的方式判断,而采用宏定义SUCCEEDED和FAILED。但是对于返回值为S_FALSE,该值为0x00000001,用该宏定义判断为真,该值的原意也是函数调用成功,返回值为FALSE。这样,在判断调用某个接口的函数返回值时,如果用宏定义来判断,那么返回S_FALSE时会出错。因为S_FALSE一般是有错的时候返回,而SUCCEEDED宏会认为S_FALSE为真,有什么办法可以简单而正确的判断HRESULT的值的正确性?

解决方案 »

  1.   

    你的意思就是说SUCCEEDED只能判断有没有返回,而不能判断返回有效无效。是不是不能使用这样的语句;
    HRESULT hr=....;
    if(hr==S_FALSE)...
    不明白。另外可以不可以使用异常捕捉来避免你所说的情况?共同借鉴。
      

  2.   

    对,因为HRESULT的值表示成功的有多个,表示失败的也有多个。假如直接用hr==S_FALSE,那么其他如果hr==E_FAIL,此时实际是返回失败,只用hr==S_FALSE判断,显然会出错。HRESULT值是用32bit来表示的,最高位bit为成功或失败的标志位。比如0x80000405就是失败的,0x00000000就是成功该宏定义如下,在winerror.h中
    #define SUCCEEDED(Status) ((HRESULT)(Status) >= 0)
    #define FAILED(Status) ((HRESULT)(Status)<0)问题麻烦是S_FALSE是0x00000001,是表示函数调用成功,但返回值为FALSE
    所以用以上宏判断时,S_FALSE是返回TRUE的,但实际上如果返回值为S_FALSE,那肯定是有错的。例如:

    hr=m_pDevEnum->CreateClassEnumerator(refClsid,&pClassEnum,0);
    if(FAILED(hr))

        return hr;
     }
    当hr=S_FALSE时,FAILED(hr)必定为FALSE, 因为S_FALSE=0x00000001,宏替换后为
    if(0x00000001<0)
    {
     return hr;
    }
    显然是不会进入 return hr的。
    但此时pClassEnum实际为NULL。
    我想知道的是有什么简便的方法判断。不想在所有判断后加上判断是否为S_FALSE,或者判断指针为空。
    不知道为什么com设计的时候要定义S_FALSE为成功?
      

  3.   

    看来只有先判断是否SUCCEED之后再判断是否是S_FALSE了。