这是server error翻译MTTYERROR.C的部分代码,非常好的通用错误报告函数:
DWORD ErrorExtender(DWORD dwError, char ** szBuffer)
{
    DWORD dwRes = 0;
    dwRes = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | 80 ,
                          NULL, dwError,
                          MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
                          (LPTSTR) szBuffer, 0, NULL);
    if (dwRes == 0) {
        *szBuffer = LocalAlloc(LPTR, 1);
void ErrorReporter(char * szMessage)
{
    char * szFormat = "Error %d: %s.\n\r%s\r\n";    // format for wsprintf
    char * szExtended;      // error string translated from error code
    char * szFinal;        // final string to report
    DWORD dwExtSize;
    DWORD dwErr;
    dwErr = GetLastError();
    /*
        Get error string from system
    */
    dwExtSize = ErrorExtender(dwErr, &szExtended);
   
    /*
        allocate buffer for error string from system, passed in string
        and extra stuff from the szFormat string
    */
    szFinal = LocalAlloc(LPTR, strlen(szMessage) + dwExtSize + 30);
    if (szFinal == NULL) // if no final buffer, then can't format error
        MessageBox(ghwndMain, "Cannot properly report error.", "Fatal Error", MB_OK);
    else {
        wsprintf(szFinal, szFormat, dwErr, szMessage, szExtended);
        OutputDebugString(szFinal);
        if (DISPLAYERRORS(TTYInfo))
            MessageBox(ghwndMain, szFinal, NULL, MB_OK);
        LocalFree(szFinal);                  // free final buffer
    }
    /*
        free extended string buffer
    */
    LocalFree(szExtended);
    return;
}
        return 1;
    }
    return dwRes;
}
一开始看到红字的部分感觉非常奇怪,查了MSDN才明白
lpBuffer
A pointer to a buffer that receives the null-terminated string that specifies the formatted message. If dwFlags includes FORMAT_MESSAGE_ALLOCATE_BUFFER, the function allocates a buffer using the LocalAlloc function, and places the pointer to the buffer at the
address specified in lpBuffer.
This buffer cannot be larger than 64K bytes.
因为使用了FORMAT_MESSAGE_ALLOCATE_BUFFERFLAG,函数用LocalAlloc申请内存,并把(指向)LocalAlloc申请到的内存(用T代表)的指针(的地址)放到 lpBuffer指定的地址中?我这翻译真不像那么回事。
我的理解是一个指针的内容是另一个指针的地址,很容易就想到指针的指针。上面的代码就好理解了。
我的调试记录:进入函数ErrorReporter后执行 char * szExtended;    这时候 szExtended的地址是0x002df854,值是一个内存地址0xcccccccc,而内存地址0xcccccccc指向的内容是无效的。运行到ErrorExtender内,char ** szBuffer是形参,它的地址是0x002df75c因为这是一个指向指针的指针所以它的值应该是另一个指针的地址,传递过来的实参确实就是指针szExtended的地址:0x002df854,所以szBuffer的值是0x002df854,这个值是一个内存地址,地址的内容是指针szExtended的内容0xcccccccc。再运行FormatMessage,这时候地址0
x002df854里的内容变成了0x00377fc0, 这是FormatMessageLocalAlloc申请到的内存的首地址。其实就是改变了szExtended的内容,使它指向了这个内存块。函数返回后szExtended的值就是错误信息字符串的首地址。
我们再来看这句话:and places the pointer to the buffer at the address specified in lpBuffer.,现在可以理解得很清楚了:把指向buffer(错误信息字符串)pointer放到 lpBuffer.的地址(的内存)中,见如下示意:
            指针szBuffer                                                     
szExtended的地址0x002df854 --》 指针szExtended
                     另一个地址0x00377fc0  --》错误信息字符串首地址
                                 |——》错误信息字符串
这就是二次间指,先到szBuffer的地址的值,得到另一个内存地址,再用这个地址得到另一个值。间接访问已经够让人头大了,这个二次间指更让人晕头转向。
坚定指针的内容是地址的革命方针,高举“DEBUG”大旗,一切指针问题都是纸老虎。
Skystalker
转裁请注明出处

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。