Windows Embedded Compact.
Trying to send and receive a message with MsgQueue.
Looks like the write is working but read gives the incorrect parameters error.
Any ideas what is missing?
I am not sure about the create queue function. It says that it must be called twice to get a read or write handle - is this right ?
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;
}
EDIT
Here is the working Read Function after @WhozCraig and another issue found incase anyone else needs this:
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;
}
Yes, that is how you setup a message queue fro sending/receiving. Two opens are generally used.
I believe the problem with your ReadMsgQueue()
invocation is the received-size parameter. It is a LPDWORD, and must not be NULL. you're currently doing this:
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
);
You're passing NULL. You need to do this instead:
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
);
It is unclear to me whether the last parameter, the received message flags out-paramter can be NULL. It is not specifically called out in the documentation like the size-read DWORD address is, which clearly states This parameter cannot be NULL
, as do other params. So your mileage may vary.