在调用一个api函数以后,如果函数失败,通常可以紧接着调用另一个api函数“getlasterror”来返回一个错误代码,下面这个类可以根据windows定义的错误代码,查找到用文字表示的错误信息:
00001: #ifndef _yhb_syserror_included_
00002: #define _yhb_syserror_included_
00003:
00004: #include <stdexcept>
00005: #include <string>
00006:
00007: namespace yhb {
00008:
00009: class syserror
00010: : public std::runtime_error
00011: {
00012: public:
00013: syserror(int err=0)
00014: : runtime_error(makemsgfromerrornum(err))
00015: {}
00016: syserror(const char *custommsg, int err = 0)
00017: : runtime_error(makemsgfromerrornum(custommsg, err))
00018: {}
00019: static std::string makemsgfromerrornum(unsigned err = 0);
00020: static std::string makemsgfromerrornum(const char *custommsg, unsigned err = 0);
00021: };
00022:
00023: } // end of namespace
00024:
00025: #endif
syserror从std::runtime_error派生,因此可以被抛出并被作为std::exception捕获。
如果不想使用异常,也可以用它的两个静态方法来返回错误信息。
实现
00001: #include "stdafx.h"
00002: #include "./syserror.h"
00003: #include <sstream>
00004: #include <lmerr.h>
00005:
00006: #define win32_lean_and_mean
00007: #include <windows.h>
00008:
00009: using namespace std;
00010:
00011: namespace yhb {
00012:
00013: /************************************************************************
00014: 管理用loadlibrary()加载的模块句柄
00015: ************************************************************************/
00016: class module {
00017: public:
00018: explicit module(hmodule handle=0)
00019: : handle_(handle)
00020: {}
00021: ~module() {
00022: free();
00023: }
00024: module & operator = (hmodule handle) {
00025: free();
00026: handle_ = handle;
00027: return *this;
00028: }
00029: bool isvalid() const { return 0!=handle_; }
00030: operator hmodule() const { return handle_; }
00031: private:
00032: module(const module &);
00033: module & operator = (const module &);
00034: void free() {
00035: if (0!=handle_) {
00036: ::freelibrary(handle_);
00037: handle_ = 0;
00038: }
00039: }
00040: hmodule handle_;
00041: };
00042:
00043: /************************************************************************
00044: syserror
00045: ************************************************************************/
00046: string syserror::makemsgfromerrornum(unsigned err/* =0 */) {
00047: if (0==err) {
00048: err = getlasterror();
00049: if (noerror==err)
00050: return "no error!";
00051: }
00052: module module;
00053: dword flag = format_message_ignore_inserts | format_message_from_system;
00054: if (err >= nerr_base && err <= max_nerr) {
00055: module = loadlibraryexa("netmsg.dll", 0, load_library_as_datafile);
00056: if (module.isvalid())
00057: flag |= format_message_from_hmodule;
00058: }
00059: char buf[1024];
00060: if (formatmessagea(flag, static_cast<hmodule>(module),
00061: err, makelangid(lang_neutral, sublang_default),
00062: buf, sizeof(buf), 0))
00063: {
00064: return buf;
00065: } else {
00066: ostringstream os;
00067: os << "unknown error: " << err << " (0x" << hex << err << );
00068: return os.str();
00069: }
00070: }
00071:
00072: string syserror::makemsgfromerrornum(const char *custommsg, unsigned err/* =0 */) {
00073: string result(custommsg);
00074: result += ;
00075: result += makemsgfromerrornum(err);
00076: return result;
00077: }
00078:
00079: } //end of namespace
c++里一种比较常用的方法,是将资源封装成一个类,在析构的时候释放该资源,比如上面的module,析构的时候调用freelibrary。
文章整理:西部数码--专业提供域名注册、虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!


