Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1586963
  • 博文数量: 441
  • 博客积分: 20087
  • 博客等级: 上将
  • 技术积分: 3562
  • 用 户 组: 普通用户
  • 注册时间: 2006-06-19 15:35
文章分类

全部博文(441)

文章存档

2014年(1)

2012年(1)

2011年(8)

2010年(16)

2009年(15)

2008年(152)

2007年(178)

2006年(70)

分类: C/C++

2008-10-22 09:43:11

通过GetLastError()能得到windows api函数操作失败的错误代码,而FormatMessage函数则可以将错误代码转换为表示错误原因的字符串, 让你知道到底是什么错误。

下面的头文件,是 "Multitheading Applications in Win32(侯捷译)"一书中的关于错误处理的示例, 通过宏MTVERIFY就可以知道调用的windows api函数错在什么地方:

/*
* MtVerify.h
*
* Error handling for applications in
* "Multitheading Applications in Win32"
*
* The function PrintError() is marked as __inline so that it can be
* included from one or more C or C++ files without multiple definition
* errors. For the examples in this book, this works fine.
* To use the PrintError() in an application, it should be taken out,
* placed in its own source file, and the "__inline" declaration removed
* so the function will be globally available.
*/


#pragma comment( lib, "USER32" )

#include <crtdbg.h>
#define MTASSERT(a) _ASSERTE(a)


#define MTVERIFY(a) if (!(a)) PrintError(#a,__FILE__,__LINE__,GetLastError())

__inline void PrintError(LPSTR linedesc, LPSTR filename, int lineno, DWORD errnum)
{
    LPSTR lpBuffer;
    char errbuf[256];

#ifdef _WINDOWS
    char modulename[MAX_PATH];
#else // _WINDOWS

    DWORD numread;
#endif // _WINDOWS

    
    FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER
        | FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        errnum,
        LANG_NEUTRAL,
        (LPTSTR)&lpBuffer,
        0,
        NULL );
    
    wsprintf(errbuf, "\nThe following call failed at line %d in %s:\n\n"
        " %s\n\nReason: %s\n", lineno, filename, linedesc, lpBuffer);

#ifdef _WINDOWS
    GetModuleFileName(NULL, modulename, MAX_PATH);
    MessageBox(NULL, errbuf, modulename, MB_ICONWARNING|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
#else
    WriteFile(GetStdHandle(STD_ERROR_HANDLE), errbuf, strlen(errbuf), &numread, FALSE );
    Sleep(3000);    
#endif

    exit(EXIT_FAILURE);
}


下面的例子展示了如何使用这个宏:

// Error.c

#define WIN32_LEAN_AND_MEAN

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "mtverify.h"

DWORD WINAPI ThreadFunc(LPVOID);

int main()
{
    HANDLE    hThread;
    DWORD    dwExitCode = 0;
    DWORD    dwThreadID;


    MTVERIFY( hThread = CreateThread(NULL, 0, ThreadFunc, (LPVOID)1, 0, &dwThreadID) );
    if ( hThread )
        printf("Thread launched.\n");

    MTVERIFY(CloseHandle(hThread));

    for ( ;; )
    {
        BOOL rc;
        MTVERIFY( rc = GetExitCodeThread(hThread, &dwExitCode) );
        if ( rc && dwExitCode != STILL_ACTIVE )
            break;
    }

    printf("Thread returned %d\n", dwExitCode);

    return EXIT_SUCCESS;
}

DWORD WINAPI ThreadFunc(LPVOID lp)
{
    printf("Thread running.\n");
    return 0;
}



在上面的代码中, CloseHandle(hThread) rc = GetExitCodeThread(hThread, &dwExitCode)之前调用,使得hThread句柄无效,这样,我们运行程序,就会得到如下的结果:

Thread launched.
Thread running.

The following call failed at line 27 in e:\thread\error\e
rror.c:

    rc = GetExitCodeThread(hThread, &dwExitCode)

Reason: The handle is invalid.

我们自己写相关的程序,完全可以使用上面的宏, 来得到函数调用失败的原因。
阅读(2245) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~