ReadMsgQueue返回ERROR_INVALID_PARAMETER

时间:2013-11-17 03:20:53

标签: c# c++ c windows windows-ce

Windows Embedded Compact。

Trying to send and receive a message with MsgQueue.

看起来写操作正常但读取错误参数错误。

缺少什么想法?

我不确定创建队列功能。它说它必须被调用两次以获得读或写句柄 - 这是对的吗?

    int main()
    {



        MSGQUEUEOPTIONS options = {0};

        options.dwSize = sizeof(options); // 
        options.dwFlags = MSGQUEUE_NOPRECOMMIT;
        options.dwMaxMessages = 10000; // msg max for queue
        options.cbMaxMessage = 50; // max number of bytes in each msg





        options.bReadAccess = TRUE; // read
        HANDLE hRead = CreateMsgQueue(LPCWSTR("MSG_QUEUE"), &options);
        if ( hRead == NULL )
        {
            printf("CreateMsgQueue hRead failed! Err code: %d\n", GetLastError());
        }

        // Thread A will read msg queue
        HANDLE hTg = CreateThread(NULL, 0, threadA, hRead, 0, 0);
        if ( NULL == hTg )   
        {
            printf("CreateThread failed - A!\n");
            return 1;
        }

        Sleep(1000); //give time before sending msg


        options.bReadAccess = FALSE; // write to
        HANDLE hWrte = CreateMsgQueue(LPCWSTR("MSG_QUEUE"), &options);
        if ( hWrte == NULL )
        {
            printf("CreateMsgQueue hWrte failed! Err code: %d\n", GetLastError());
        }

        // Thread B write to queue
        HANDLE hTt = CreateThread(NULL, 0, threadB, hWrte, 0, 0);
        if ( NULL == hTt )   
        {
            printf("CreateThread failed - B!\n");
            return 1;
        }
        // quit on <ENTER> key
        getchar();

}

DWORD WINAPI threadB(LPVOID lpParameter)
{
    HANDLE msgH = HANDLE(lpParameter);
    if ( msgH == NULL)
    {
        printf("Null handle in write!\n");
    }

    char message[10] = "ABCDEFGHI";

    printf("Size of message sent: %d bytes\n", sizeof(message));


    // know that a queue is not full and that it's safe to write
    WaitForSingleObject(msgH, INFINITE);

    BOOL ret = WriteMsgQueue(
        msgH,
        &message, 
        sizeof(message),
        INFINITE,
        NULL);
    if ( ret == FALSE )
    {
        printf("WriteMsgQueue failed! Err code: %d\n", GetLastError());
    }

    return 0;
}

DWORD WINAPI threadA(LPVOID lpParameter)
{
    HANDLE hQ = HANDLE(lpParameter);
    if ( hQ == NULL )
    {
        printf("null handle in read!\n");
    }

    char readIn[50] = {0};
    LPDWORD  numRead = 0;
    //DWORD flag;

    // need to wait on sinfle object
    WaitForSingleObject(hQ, INFINITE);

    BOOL ret = ReadMsgQueue(
        hQ,
        &readIn,
        DWORD(sizeof(readIn)),
        numRead,
        INFINITE,
        NULL
        );

    if ( ret == FALSE )
    {
        printf(" ReadMsgQueue failed! Err code: %d\n", GetLastError());
    }

    printf("Size received: %d\n", numRead);
    printf("Msg Received: %s\n", readIn);


    return 0;
}

编辑

以下是@WhozCraig之后的工作读取功能以及其他任何人需要的问题:

DWORD WINAPI threadA(LPVOID lpParameter)
{
    HANDLE hQ = HANDLE(lpParameter);
    if ( hQ == NULL )
    {
        printf("null handle in read!\n");
    }

    char readIn[50] = {0};
    DWORD  numRead = 0;
    DWORD flag;

    // need to wait on sinfle object
    WaitForSingleObject(hQ, INFINITE);

    BOOL ret = ReadMsgQueue(
        hQ,
        &readIn,
        sizeof(readIn),
        &numRead,
        INFINITE,
        &flag
        );

    if ( ret == FALSE )
    {
        printf(" ReadMsgQueue failed! Err code: %d\n", GetLastError());
    }

    printf("Size received: %d\n", numRead);
    printf("Msg Received: %s\n", readIn);

    return 0;
}

2 个答案:

答案 0 :(得分:2)

是的,这就是您设置发送/接收消息队列的方式。通常使用两次打开。

我认为ReadMsgQueue()调用的问题是receive-size参数。它是LPDWORD,不能为NULL。你现在正在这样做:

char readIn[50] = {0};
LPDWORD  numRead = 0; // SHOULD NOT BE A POINTER

// need to wait on sinfle object
WaitForSingleObject(hQ, INFINITE);

BOOL ret = ReadMsgQueue(
    hQ,
    &readIn,
    DWORD(sizeof(readIn)),
    numRead, // THIS IS A PROBLEM
    INFINITE,
    NULL
    );

你传递的是NULL。你需要这样做:

char readIn[50] = {0};
DWORD numRead = 0; // NOTE: regular DWORD

// need to wait on sinfle object
WaitForSingleObject(hQ, INFINITE);

BOOL ret = ReadMsgQueue(
    hQ,
    &readIn,
    DWORD(sizeof(readIn)),
    &numRead, // NOTE: address of DWORD
    INFINITE,
    NULL
    );

我不清楚最后一个参数,即收到的消息标志out-paramter是否可以为NULL。在文档中没有特别调用类似于大小读取的DWORD地址,它清楚地表明This parameter cannot be NULL,其他参数也是如此。所以你的里程可能会有所不同。

答案 1 :(得分:1)

两件事:

1)是:如果你想读写,那么你必须调用两次CreateMsgQueue:第一个用于只写句柄,第二个用于(不同!)只读句柄。

2)您的缓冲区为lpBuffer。如果您声明“char message [10];”,则必须传递message NOT &message

3)出于同样的原因,您必须通过readIn,而不是&readIn。我猜这可能是你的ERROR_INVALID_PARAMETER的原因。

相关问题