-3

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

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

我的第一个程序如下所示:

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()然后给出与提交给我的第一个程序不同的参数字符串。它看起来很奇怪,不可读......

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

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

4

1 回答 1

0

最后我找到了解决我的问题的方法。我刚刚再次复制了 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] = '\0';

        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;
}
于 2015-02-18T15:19:19.817 回答