【问题标题】:ReadMsgQueue Returns ERROR_INVALID_PARAMETERReadMsgQueue 返回 ERROR_INVALID_PARAMETER
【发布时间】:2013-11-17 03:20:52
【问题描述】:

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;
}

【问题讨论】:

  • 什么是停止main() 完成并在启动两个线程后返回程序终止?就我所见。。什么都没有。您可能希望等待这两个创建的线程句柄。
  • @whozcraig:抱歉,试图取出多余的东西。我有 // 退出 键 getchar();

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


【解决方案1】:

是的,这就是您为发送/接收设置消息队列的方式。一般用两个开。

我相信你的ReadMsgQueue() 调用的问题是接收大小参数。它是一个 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
    );

我不清楚最后一个参数,接收到的消息标志输出参数是否可以为 NULL。它没有像 size-read DWORD 地址那样在文档中特别指出,它明确指出This parameter cannot be NULL,其他参数也是如此。所以你的里程可能会有所不同。

【讨论】:

  • 噢噢噢!粗鲁的好眼光,我是这些类型的新手,我忘了 LP 是长指针或其他指针,让我试试。
  • 有趣,我仍然得到错误代码 87。也许 sizeof() 上的演员表不正确......但你指出的明确是一个问题......(我拥有的所有代码该线程正是正在运行的)
  • 可能标志不能为NULL
【解决方案2】:

两件事:

1) 是的:如果要读写,则必须调用 CreateMsgQueue 两次:第一次用于只写句柄,第二次用于(不同!)只读句柄。

2) 你的缓冲区是lpBuffer。如果你声明“char message[10];”,那么你必须通过message,NOT&amp;message。

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

【讨论】:

  • 对于#2 和#3,既不需要也不需要。该参数是一个 LPVOID。给定char message[10],message 和&amp;message 的地址 是相同的。只有 type 不同。 (一个是char*,另一个是char (*)[10],在两种的情况下,类型在转换void*时无论如何都会丢失。message是一个指针 而不是一个固定的数组,你是完全正确的。
  • 也就是说,查看接收大小 DWORD 通过地址传递的读取大小。它是一个 NULL 指针,它不能是。我相信这是真正的问题。他将 NULL 作为 LPDWORD 大小接收器传递,并且根据文档,“存储在 lpBuffer 中的字节数。此参数不能为 NULL。”
  • @whozcraig:NULL 用于标志 - 最后一个参数。读取大小不是第三个参数sizeof(message)吗​​?
  • @paulsm4:好的,谢谢#1,我假设我用相同的名称做对了,然后只更改了 bReadAccess 参数...?
  • @P.S. read-size 是您提供的缓冲区空间量。我认为问题在于 Fourth 参数(实际读取了多少字节的结果)。是的,我实际上并没有运行它,但是 10,000 英尺的视图看起来是正确的。您所要做的就是翻转访问标志。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-04
  • 1970-01-01
相关资源
最近更新 更多