C++ 我想复制(wchar_t*)缓冲区中的数据,但我无法这样做,因为还有其他不兼容的类型,类型转换但没有得到结果?

C++ 我想复制(wchar_t*)缓冲区中的数据,但我无法这样做,因为还有其他不兼容的类型,类型转换但没有得到结果?,c++,c,windows,winapi,C++,C,Windows,Winapi,我希望在一个实例上打印缓冲区数据,避免所有其他wprintf实例,但无法转换与缓冲区兼容类型的数据 看看代码: 请告诉我如何度过难关: DWORD PrintEvent(EVT_HANDLE hEvent) { DWORD status = ERROR_SUCCESS; PEVT_VARIANT pRenderedValues = NULL; WCHAR wsGuid[50]; LPWSTR pwsSid = NULL; // // Beginn

我希望在一个实例上打印缓冲区数据,避免所有其他wprintf实例,但无法转换与缓冲区兼容类型的数据

看看代码:

请告诉我如何度过难关:

DWORD PrintEvent(EVT_HANDLE hEvent)
{
    DWORD status = ERROR_SUCCESS;
    PEVT_VARIANT pRenderedValues = NULL;
    WCHAR wsGuid[50];
    LPWSTR pwsSid = NULL;

    //
    // Beginning of functional Logic
    //
    for (;;)
    {

        if (!EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedValues, &dwBufferUsed, &dwPropertyCount))
        {
            if (ERROR_INSUFFICIENT_BUFFER == (status = GetLastError()))
            {
                dwBufferSize = dwBufferUsed;
                dwBytesToWrite = dwBufferSize;
                pRenderedValues = (PEVT_VARIANT)malloc(dwBufferSize);
                if (pRenderedValues)
                {
                    EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedValues, &dwBufferUsed, &dwPropertyCount);
                }
                else
                {
                    printf("malloc failed\n");
                    status = ERROR_OUTOFMEMORY;
                    break;
                }
            }
        }
        Buffer = (wchar_t*) malloc (1*wcslen(pRenderedValues[EvtSystemProviderName].StringVal));

        //
        // Print the values from the System section of the element.
        wcscpy(Buffer,pRenderedValues[EvtSystemProviderName].StringVal);

        int i = wcslen(Buffer);

        if (NULL != pRenderedValues[EvtSystemProviderGuid].GuidVal)
        {
            StringFromGUID2(*(pRenderedValues[EvtSystemProviderGuid].GuidVal), wsGuid, sizeof(wsGuid)/sizeof(WCHAR));
            wcscpy(Buffer+i,(wchar_t*)pRenderedValues[EvtSystemProviderGuid].GuidVal);
            wprintf(L"Provider Guid: %s\n", wsGuid);
        }
//在包含guidval后在屏幕上显示“???????”告诉我复制它的正确方法

        wprintf(L"Buffer = %ls",Buffer);
//还告诉如何将无符号值复制到缓冲区

        wprintf(L"EventID: %lu\n", EventID);

        wprintf(L"Version: %u\n", pRenderedValues[EvtSystemVersion].ByteVal);
        wprintf(L"Level: %u\n", pRenderedValues[EvtSystemLevel].ByteVal);


        wprintf(L"EventRecordID: %I64u\n", pRenderedValues[EvtSystemEventRecordId].UInt64Val);

        if (EvtVarTypeNull != pRenderedValues[EvtSystemActivityID].Type)
        {
            StringFromGUID2(*(pRenderedValues[EvtSystemActivityID].GuidVal), wsGuid, sizeof(wsGuid)/sizeof(WCHAR));
            wprintf(L"Correlation ActivityID: %s\n", wsGuid);
        }

        if (EvtVarTypeNull != pRenderedValues[EvtSystemRelatedActivityID].Type)
        {
            StringFromGUID2(*(pRenderedValues[EvtSystemRelatedActivityID].GuidVal), wsGuid, sizeof(wsGuid)/sizeof(WCHAR));
            wprintf(L"Correlation RelatedActivityID: %s\n", wsGuid);
        }

        wprintf(L"Execution ProcessID: %lu\n", pRenderedValues[EvtSystemProcessID].UInt32Val);
        wprintf(L"Execution ThreadID: %lu\n", pRenderedValues[EvtSystemThreadID].UInt32Val);
        wprintf(L"Channel: %s\n",pRenderedValues[EvtSystemChannel].StringVal);
        wprintf(L"Computer: %s\n", pRenderedValues[EvtSystemComputer].StringVal);



        //
        // Final Break Point
        //

        break;
    }
}

第一个错误是开始写入缓冲区时:

Buffer = (wchar_t*) malloc (1*wcslen(pRenderedValues[EvtSystemProviderName].StringVal));
wcscpy(Buffer,pRenderedValues[EvtSystemProviderName].StringVal);
StringVal指向带有尾随空字节的宽字符串,因此您应该

Buffer = malloc (sizeof(wchar_t)*(wcslen(pRenderedValues[EvtSystemProviderName].StringVal)+1));
甚至更好

Buffer = wcsdup(pRenderedValues[EvtSystemProviderName].StringVal);
第二个错误是追加GUID。

您没有分配足够的内存,只是在追加已满的缓冲区。并且您正在附加原始GUID,而不是GUID字符串。你应该替换

int i = wcslen(Buffer);
wcscpy(Buffer+i,(wchar_t*)pRenderedValues[EvtSystemProviderGuid].GuidVal);
有点像

// Attention: memory leak if realloc returns NULL! So better use a second variable for the return code and check that before assigning to Buffer.
Buffer = realloc(Buffer, wcslen(Buffer) + wcslen(wsGuid) + 1);
wcscat(Buffer,wsGuid);
另外:

Buffer = (wchar_t*) malloc (1*wcslen(pRenderedValues[EvtSystemProviderName].StringVal));
wcscpy(Buffer,pRenderedValues[EvtSystemProviderName].StringVal);
此外,您应该为EvtRender做更好的错误检查。在访问pRenderedValues[i]之前,您应该检查dwPropertyCount

顺便说一句,
wprintf(L“Buffer=%s”,Buffer)(使用%s而不是%ls)对于wprintf已足够


最后一个问题是:如果要将无符号值附加到缓冲区,可以使用
wsprintf
写入字符串。如果你能做到C++,那么你就应该考虑使用<代码> STD::WScGe>代码。在分配合适大小的缓冲区方面,这对您来说要容易得多。

在输出中,我得到的是PrendedeValues[EvtSystemProviderName].StringVal的正确字符串,但在PrendedeValues[EvtSystemProviderGuid].GuidVal的情况下,我得到的是垃圾文本,Evt渲染错误检查和以前一样,我在控制台上打印所有内容,如何在缓冲区中适当地获得它???@D.a.Danekhail:如果您认为我的答案回答了您的问题,请接受。谢谢。这是什么语言?它既不能是C又不能是C++。