WinMain 参数 -> 邮槽 -> 文件 -> 编码?

WinMain Parameter -> Mailslot -> File -> Encoding?

我遇到了以下问题: 一个应用程序每秒调用一个带有一些参数的 C++ 程序来从该应用程序中提取数据。 C++ 程序是一个 WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) 来实现控制台-window 不显示给用户。 此 "first program" 检查数据,然后将其写入由我的 "second program" 托管的邮槽(只是一个普通的 int main() C++)。 这已经像上面写的那样工作了,但是当我尝试读取邮筒的内容时,编码似乎有所不同,因为我的参数不可读并且字符串的长度不同。

两个程序都在其属性中使用 Unicode。我尝试使用 LPWSTR(对于 Unicode)和 LPCSTR(对于 ANSI)以及相应的函数 ...W...A,但我没有让它工作。 下面我写了我的 "LPCSTR-Version" 我的 2 个程序。

我的第一个程序是这样的:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
{
    // here I do: string test = szCmdLine;
    // the parameters are like: "k1234.1234 4321.321 0 1"
    // so there is no special character, just two double and to int
    // asking for minimum length and number of spaces in it to get number of parameters
    // if there is anything not ok I return "",
    // if there is all ok, I return szCmdLine.
    LPCSTR message = processParameter((LPCSTR)szCmdLine);

    if (strcmp('', message) == 0)
        return 0;

    HANDLE hSlot;

    hSlot = CreateFile(
        L"\\.\mailslot\name\of\the\slot",
        GENERIC_WRITE,              // DesiredAccess
        FILE_SHARE_READ,            // ShareMode
        (LPSECURITY_ATTRIBUTES)NULL,// SecurityAttributes
        OPEN_EXISTING,              // CreationDisposition
        FILE_ATTRIBUTE_NORMAL,      // FlagsAndAttributes
        (HANDLE)NULL                // TemplateFile
        );

    if (hSlot == INVALID_HANDLE_VALUE)
        return 0;

    // send message
    BOOL fResult;
    DWORD cbWritten;

    fResult = WriteFile(
        hSlot,
        message,
        (DWORD)(lstrlenA(message) + 1)*sizeof(char),
        &cbWritten,
        (LPOVERLAPPED)NULL
        );  

    // Handle Clean-up
    CloseHandle(hFile);

    return 0;
}

在我的第二个程序中是这样的:

HANDLE hMailSlot    = NULL;

BOOL WINAPI createMailSlot()
{
    hMailSlot = CreateMailslot(
        L"\\.\mailslot\name\of\the\slot",
        0,                          // no maximum message size 
        MAILSLOT_WAIT_FOREVER,      // no time-out for operations 
        (LPSECURITY_ATTRIBUTES)NULL // default security
        );

    if (hMailSlot == INVALID_HANDLE_VALUE)
    {
        printf("CreateMailslot failed with error %d\n", GetLastError());
        return FALSE;
    }
    else
    {
        printf("Mailslot created successfully.\n");
    }

    return TRUE;
}

void processMessage(LPCSTR msg)
{
    string message = msg;

    // DEBUGGING
    cout << "Message: " << message << endl;
    cout << "length:  " << message.length() << endl;

    // do other things...
}

BOOL readSlot()
{
    DWORD cbMessage;
    DWORD cMessage;
    DWORD cbRead;
    BOOL fResult;
    LPCSTR lpszBuffer;
    CHAR achID[80];
    DWORD cAllMessages;
    HANDLE hEvent;
    OVERLAPPED ov;

    cbMessage = cMessage = cbRead = 0;

    hEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("ExampleSlot"));
    if (NULL == hEvent)
    {
        return FALSE;
    }
    ov.Offset = 0;
    ov.OffsetHigh = 0;
    ov.hEvent = hEvent;

    fResult = GetMailslotInfo(
        hMailSlot,      // mailslot handle 
        (LPDWORD)NULL,  // no maximum message size 
        &cbMessage,     // size of next message 
        &cMessage,      // number of messages 
        (LPDWORD)NULL   // no read time-out
        );
    if (!fResult)
    {
        printf("GetMailslotInfo failed with %d.\n", GetLastError());
        CloseHandle(hEvent);
        return FALSE;
    }

    if (cbMessage == MAILSLOT_NO_MESSAGE)
    {
        printf("Waiting for a message...\n");
        CloseHandle(hEvent);
        return TRUE;
    }

    cAllMessages = cMessage;

    while (cMessage != 0)  // retrieve all messages
    {
        // Create a message-number string. 
        StringCchPrintfA(
            achID,
            80,
            "",
            cAllMessages - cMessage + 1,
            cAllMessages);

        // Allocate memory for the message.
        lpszBuffer = (LPCSTR)GlobalAlloc(
            GPTR,
            cbMessage
            );
        if (NULL == lpszBuffer)
        {
            CloseHandle(hEvent);
            return FALSE;
        }

        fResult = ReadFile(
            hMailSlot,
            (LPVOID)lpszBuffer,
            cbMessage,
            &cbRead,
            &ov
            );

        if (!fResult)
        {
            printf("ReadFile failed with %d.\n", GetLastError());
            GlobalFree((HGLOBAL)lpszBuffer);
            CloseHandle(hEvent);
            return FALSE;
        }

        // process Message
        processMessage(lpszBuffer);

        // Concatenate the message and the message-number string. 

        StringCbCatA(
            (STRSAFE_LPSTR)lpszBuffer,
            cbMessage,
            achID
            );

        GlobalFree((HGLOBAL)lpszBuffer);

        fResult = GetMailslotInfo(
            hMailSlot,      // mailslot handle 
            (LPDWORD)NULL,  // no maximum message size 
            &cbMessage,     // size of next message 
            &cMessage,      // number of messages 
            (LPDWORD)NULL   // no read time-out
            );

        if (!fResult)
        {
            printf("GetMailslotInfo failed (%d)\n", GetLastError());
            CloseHandle(hEvent);
            return FALSE;
        }
    }
    CloseHandle(hEvent);
    return TRUE;
}

int main()
{
    if(!createMailSlot())
        return 1;

    while (true)
    {
        // check Mailslot for messages
        readSlot();

        Sleep(1000);
    }
    return 0;
}

processMessage() 给出的参数字符串与提交给我的第一个程序的参数字符串不同。它看起来很奇怪而且不可读...

我的问题有解决方案吗?我的错在哪里?

编辑: 我编辑了包括源代码在内的整个问题,以显示我的最新版本。

我终于找到了解决问题的方法。 我只是再次复制了 MSDN (https://msdn.microsoft.com/en-us/library/windows/desktop/aa365576%28v=vs.85%29.aspx) 的示例代码,然后用谷歌搜索了一下。 我发现这个站点 http://www.johndcook.com/blog/cplusplus_strings/ 列出并解释了所有字符串表示形式。我更改了一些代码段落,这是我的工作版本:

第一个节目:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
{
    // get parameters
    char *parameter = szCmdLine;

    // validate parameters
    if (!test_parameter(parameter))
    {
        return 1;
    }

    // Convert char* to a wchar_t*
    size_t origsize = strlen(parameter) + 1;
    const size_t newsize = 100;
    size_t convertedChars = 0;
    wchar_t wcstring[newsize];
    mbstowcs_s(&convertedChars, wcstring, origsize, parameter, _TRUNCATE);
    // Source: https://msdn.microsoft.com/en-us/library/ms235631(VS.80).aspx

    HANDLE hMailSlot;

    hMailSlot = CreateFile(
        L"\\.\mailslot\name\of\the\MailSlot",    // lpFileName
        GENERIC_WRITE,              // DesiredAccess
        FILE_SHARE_READ,            // ShareMode
        (LPSECURITY_ATTRIBUTES)NULL,// SecurityAttributes
        OPEN_EXISTING,              // CreationDisposition
        FILE_ATTRIBUTE_NORMAL,      // FlagsAndAttributes
        (HANDLE)NULL                // TemplateFile
        );

    // testing mailslot
    if (hMailSlot == INVALID_HANDLE_VALUE)
    {
        return 2;
    }

    BOOL fResult;
    DWORD cbWritten;

    // convert message to TCHAR for sending
    TCHAR *message = wcstring;

    // send message
    fResult = WriteFile(
        hMailSlot,                                      // File
        message,                                        // Buffer
        (DWORD)(lstrlen(message) + 1)*sizeof(TCHAR),    // NumberOfBytesToWrite
        &cbWritten,                                     // NumberOfBytesWritten
        (LPOVERLAPPED)NULL                              // Overlapped
        );                          

    // Handle Clean-up
    CloseHandle(hMailSlot);

    return 0;
}

第二个节目:

HANDLE hMailSlot = NULL;

BOOL WINAPI createMailSlot()
{
    hMailSlot = CreateMailslot(
        L"\\.\mailslot\name\of\the\MailSlot",            // Slot Name
        0,                          // no maximum message size 
        MAILSLOT_WAIT_FOREVER,      // no time-out for operations 
        (LPSECURITY_ATTRIBUTES)NULL // default security
        );

    if (hMailSlot == INVALID_HANDLE_VALUE)
    {
        printf("CreateMailslot failed with error %d\n", GetLastError());
        return FALSE;
    }
    else
    {
        printf("Mailslot created successfully.\n");
    }

    return TRUE;
}

void processMessage(LPTSTR msg)
{
    // convert LPTSTR to string
    wchar_t *message_w = msg;
    size_t max = 100;
    char *message_c = new char[wcslen(message_w)];
    size_t message_c_size = 100;
    size_t *NumOfCharConverted = 0;
    wcstombs_s(NumOfCharConverted, message_c, message_c_size, message_w, max);
    string message(message_c);

    // processs message as string...
}

BOOL readSlot()
{
    DWORD cbMessage, cMessage, cbRead;
    BOOL fResult;
    LPTSTR lpszBuffer;
    TCHAR achID[80];
    DWORD cAllMessages;
    HANDLE hEvent;
    OVERLAPPED ov;

    cbMessage = cMessage = cbRead = 0;

    hEvent = CreateEvent(NULL, FALSE, FALSE, TEXT("ExampleSlot"));
    if (NULL == hEvent)
        return FALSE;
    ov.Offset = 0;
    ov.OffsetHigh = 0;
    ov.hEvent = hEvent;

    fResult = GetMailslotInfo(
        hMailSlot,      // mailslot handle 
        (LPDWORD)NULL,  // no maximum message size 
        &cbMessage,     // size of next message 
        &cMessage,      // number of messages 
        (LPDWORD)NULL); // no read time-out 

    if (!fResult)
    {
        printf("GetMailslotInfo failed with %d.\n", GetLastError());
        return FALSE;
    }

    if (cbMessage == MAILSLOT_NO_MESSAGE)
    {
        printf("Waiting for a message...\n");
        return TRUE;
    }

    cAllMessages = cMessage;

    while (cMessage != 0)  // retrieve all messages
    {
        // Create a message-number string. 

        StringCchPrintf((LPTSTR)achID,
            80,
            TEXT(""), //TEXT("\nMessage #%d of %d\n"),
            cAllMessages - cMessage + 1,
            cAllMessages);

        // Allocate memory for the message. 

        lpszBuffer = (LPTSTR)GlobalAlloc(GPTR,
            lstrlen((LPTSTR)achID)*sizeof(TCHAR) + cbMessage);
        if (NULL == lpszBuffer)
            return FALSE;
        lpszBuffer[0] = '[=11=]';

        fResult = ReadFile(
            hMailSlot,
            lpszBuffer,
            cbMessage,
            &cbRead,
            &ov);

        if (!fResult)
        {
            printf("ReadFile failed with %d.\n", GetLastError());
            GlobalFree((HGLOBAL)lpszBuffer);
            return FALSE;
        }


        processMessage(lpszBuffer);

        // Concatenate the message and the message-number string. 

        StringCbCat(lpszBuffer,
            lstrlen((LPTSTR)achID)*sizeof(TCHAR) + cbMessage,
            (LPTSTR)achID);

        // Display the message. 

        _tprintf(TEXT("Contents of the mailslot: %s\n"), lpszBuffer);

        GlobalFree((HGLOBAL)lpszBuffer);

        fResult = GetMailslotInfo(
            hMailSlot,      // mailslot handle 
            (LPDWORD)NULL,  // no maximum message size 
            &cbMessage,     // size of next message 
            &cMessage,      // number of messages 
            (LPDWORD)NULL); // no read time-out 

        if (!fResult)
        {
            printf("GetMailslotInfo failed (%d)\n", GetLastError());
            return FALSE;
        }
    }
    CloseHandle(hEvent);
    return TRUE;
}

int main()
{
    if(!createMailSlot())
        return 1;

    while (true)
    {
        // check Mailslot for messages
        readSlot();

        Sleep(1000);
    }
    return 0;
}