vb般的VC++开发(2)--COM异常与safecall

9 篇文章 0 订阅

    在COM编程中正确的处理COM异常,是增强程序鲁棒性的基础。在delphi中有safecall的概念,在vb中虽然没有提及此概念,但仍然在使用。在vc中,需要手工支持。那什么是safecall,与COM异常又有什么关系呢?

    safecall其实是约定了COM组件的提供者与调用者之间调用的方式。 safecall首先是一个stdcall,也就是说COM组件暴露的所有接口方法采用与windows API一致的stdcall调用约定。其次,safecall还要求接口方法均返回HRESULT错误代码,不能引发COM异常;调用者在调用接口方法后,均要检查HRESULT,对错误进行相应的处理。也就是说,safecall保证在方法内部封装了所有COM异常,调用者不必处理异常。

    

    例如:IProvider提供一个方法Echo,我们看不同语言不同范式的区别。

 

vb

'provider
'vb封装了COM异常和HRESULT错误代码
function Echo(sMessage as String) as String
    Echo=sMessage
end function


'caller
'vb封装了对HRESULT错误代码的处理,如有错误引发COM异常
on error resume next
MsgBox Echo("Hello World!")
 

 

vc++ -- 一般方式

//provider
//需要手工用try catch封装异常,保证所有错误均通过HRESULT返回
HRESULT Echo(BSTR bstrMessage,BSTR* pbstrValue)
{
    try
    {
         *pbstrValue=::SysAllocString(L"Hello World!");
     }
     catch(_com_error& e)
     {
          return e.Error();
     }
     return S_OK;
}

//caller

//一般方式
_bstr_t bstrValue;
HRESULT hr=pProvider->Echo(_bstr_t(L"Hello World!"),bstrValue.GetAddress());
if(FAILED(hr))
{
    //这里有两种处理方式,
    //第一种,直接返回错误
    return hr;

    //第二种,返回异常,就像vb的方式一样
    _com_util::CheckError(hr);
}

//如果provider组件是通过#import导入的,可有如下的方式调用
try
{
    _bstr_t bstrValue=pProvider->Echo(L"Hello World!");
}
catch(_com_error& e)
{
    return e.Error();
}

 

vb般的vc++

//provider
//采用自定义宏封装
HRESULT Echo(BSTR bstrMessage,BSTR* pbstrValue)
{
__SAFECALL_BEGIN;
    *pbstrValue=::SysAllocString(L"Hello World!");
__SAFECALL_END;
}

//caller
//通过#import导入
//如果是内部调用的方法,不必再检测com异常;
//因为向外暴露的方法均通过safecall对com异常进行了封装
_bstr_t bstrValue=pProvider->Echo(L"Hello World!");

 

自定义宏

#define __SAFECALL_BEGIN /
 try{/
  

#define __SAFECALL_END /
  /
 }/
 catch(_com_error& e){/
  return e.Error();/
 }/
 catch(...){/
  return E_FAIL;/
 }/
 return S_OK

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值