Windows錯誤碼轉換為錯誤資訊

來源:互聯網
上載者:User
文章目錄
  • 實現

在調用一個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。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.