D语言中国主页  D语言编辑器SciTE4D   DWin库 D语言官方网站
D语言编译器1.x最新版 OpenSource   Tango   webnews  Wiki

查看完整版本: COM组件设计与应用12 错误与异常处理

yidabu 2007-5-17 09:34

COM组件设计与应用12 错误与异常处理

COM组件设计与应用12 错误与异常处理知识若不分享 实在没有意义 http://www.d-programming-language-china.org 20070517点击下面网址查看原文:http://www.d-programming-language-china.org        by:        杨老师        下载源代码        http://www.vckbase.com/code/downcode.asp?id=2748前言        程序设计中,错误处理必不可少,而且通常要占用很大的篇幅。本回书着落在 COM 中的错误(异常)的处理方法。        在组件程序中,如果遇到错误,一般有两个方式进行处理。简单返回        对于比较简单的错误,直接返回表示错误原因的 HRESULT。比如下面几个就是常见的错误值:                         E_INVALIDARG        0x80070057        参数错误                        E_OUTOFMEMORY        0x8007000E        内存错误                        E_NOTIMPL        0x80004001        未实现                        E_POINTER        0x80004003        无效指针                        E_HANDLE        0x80070006        无效句柄                        E_ABORT        0x80004004        终止操作                        E_ACCESSDENIED        0x80070005        拒绝访问                        E_NOINTERFACE        0x80004002        不支持接口                        另外,你还可以返回自己构造 HRESULT 错误值。方法是使用宏 MAKE_HRESULT(sev,fac,code)                         参数        含义        值(二进制)                                sev 严重程度        成功        00                        成功,但有一些报告信息        01                        警告        10                        错误        11                                fac 设备信息        FACILITY_AAF        00000010010                        FACILITY_ACS        00000010100                        FACILITY_BACKGROUNDCOPY        00000100000                        FACILITY_CERT        00000001011                        FACILITY_COMPLUS        00000010001                        FACILITY_CONFIGURATION        00000100001                        FACILITY_CONTROL        00000001010                        FACILITY_DISPATCH        00000000010                        FACILITY_DPLAY        00000010101                        FACILITY_HTTP        00000011001                        FACILITY_INTERNET        00000001100                        FACILITY_ITF        00000000100                        FACILITY_MEDIASERVER        00000001101                        FACILITY_MSMQ        00000001110                        FACILITY_NULL        00000000000                        FACILITY_RPC        00000000001                        FACILITY_SCARD        00000010000                        FACILITY_SECURITY        00000001001                        FACILITY_SETUPAPI        00000001111                        FACILITY_SSPI        00000001001                        FACILITY_STORAGE        00000000011                        FACILITY_SXS        00000010111                        FACILITY_UMI        00000010110                        FACILITY_URT        00000010011                        FACILITY_WIN32        00000000111                        FACILITY_WINDOWS        00000001000                        FACILITY_WINDOWS_CE        00000011000                                code 唯一错误码        16位(bit)        你自己定义去吧                                 调用者得到返回的 HRESULT 值后,也可以使用宏 HRESULT_SEVERITY()、HRESULT_FACILITY()、HRESULT_CODE() 来取得sev错误程度、fac设备信息和 code 错误代码。错误信息接口        既然 COM 是靠各种各样的接口来提供服务的,于是很自然地就会想到,是否有一个接口能够提供更丰富的错误信息报告那?答案是:ISupportErrorInfo。下面这段代码是使用 ISupportErrorInfo 的一般方法:( 本文出处: http://www.d-programming-language-china.org )        QUOTE:                                STDMETHODIMP Cxxx::fun()                {                    ... ... ... ...                                    CComQIPtr< ICreateErrorInfo> spCEI;                    ::CreateErrorInfo( &spCEI );                                    spCEI->SetGUID( IID_Ixxx );        // 发生错误的接口IID                                    spCEI->SetSource( L"xxx.xxx" );    // ProgID                                    // 如果你的组件同时提供了帮助文件,那么就可以:                    spCEI->SetHelpContext( 0 );        // 设置帮助文件的主题号                    spCEI->SetHelpFile( L"xxx.hlp" );    // 设置帮助文件的文件名                                    spCEI->SetDescription( L"错误描述信息" );                                    CComQIPtr < IErrorInfo > spErrInfo = spCEI;                    if( spErrInfo )                        ::SetErrorInfo( 0, spErrInfo );    // 这时调用者就可以得到错误信息了                                    return E_FAIL;                }                上面是原理性代码,在我们写的程序中,不用这么麻烦。因为 ATL 已经把上述的代码给我们包装成 CComCoClass::Error() 的6个重载函数了。如此,我们可以非常简单的改写为:        QUOTE:                                STDMETHODIMP Cxxx::fun()                {                    ... ... ... ...                    return Error( L"错误描述信息" );                }        关于 try/catch        学习了 C++ 后,很多人都喜欢使用 try/catch 的异常处理结构。如果你使用 vc6.0 的ATL,编译器默认是不支持异常处理的,编译后会报告“warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify -GX”,解决方法是手工加上编译开关:        图一、加上编译开关,支持C++的异常处理结构( 本文出处: http://www.d-programming-language-china.org )        在vc.net 2003 中,编译器默认是支持异常处理结构的,所以不用特别进行设置。如果想减小目标文件的尺寸,你也可以决定不使用 C++ 异常处理,那么在项目属性中        图二、在vc.net中修改是否支持C++异常结构的编译开关( 本文出处: http://www.d-programming-language-china.org )客户端接收组件的错误信息        1、如果使用 API 方式调用组件,接收错误的方法是:        QUOTE:                                HRESULT hr = spXXX->fun()    // 调用组件功能                if( FAILED( hr ) )    // 如果发生了错误                {                CComQIPtr < ISupportErrorInfo > spSEI = spXXX;    // 组件是否提供了 ISupportErrorInfo 接口?                if( spSEI )    // 如果支持,那么                {                    hr = spSEI->InterfaceSupportsErrorInfo( IID_Ixxx );    // 是否支持 Ixxx 接口的错误处理?                    if( SUCCEEDED( hr ) )                    {    // 支持,太好了。取出错误信息                        CComQIPtr < IErrorInfo > spErrInfo;        // 声明 IErrorInfo 接口                        hr = ::GetErrorInfo( 0, &spErrInfo );    // 取得接口                        if( SUCCEEDED( hr ) )                        {                            CComBSTR bstrDes;                            spErrInfo->GetDescription( &bstrDes );    // 取得错误描述                            ......    // 还可以取得其它的信息                        }                    }                }                }                2、如果使用 #import 等包装方式调用组件,接收错误的方法是:        QUOTE:                                try                {                    ......    // 调用组件功能                    }                    catch( _com_error &e )                    {                    e.Description();    // 取得错误描述信息                    ......    // 还可以调用 _com_error 函数取得其它信息                }        编写支持错误处理的组件程序        非常简单,只要在增加 ATL 组件对象的时候选中 ISupportErrorInfo 即可。        图三、vc6.0 中,选中组件支持错误处理接口        图四、vc.net 2003 中,选中组件支持错误处理接口( 本文出处: http://www.d-programming-language-china.org )小结        阅读文章后,请下载本回的示例程序。示例程序中演示了三种错误处理方法和三种接收错误的方法,同时程序中也有比较详细的注释。( lastupdate:20070517 最新文章请访问http://www.d-programming-language-china.org )关于一大步成功社区:yidabu提倡在交流中学习,在分享中提高收集感兴趣的知识,写下心得,通过网络与别人一起分享理解一点就实践一步,收获什么就分享什么,成功就是这样一点点一步步累积起来的网络只是一个工具,只有自己身心提高才是实实在在的。d-programming-language-china.org为大家提供一个学习交流各种知识的平台
页: [1]
查看完整版本: COM组件设计与应用12 错误与异常处理