После вызова msgrcv () я получил E2BIG: на SunOS, CPP-компилятор.
Вывод следующий:
arguments:
MsgID: 335006
pointer: 0xffbfbac8
sizeof: 1040
MsgType: 0
MsgFlag: 2048
RetVal=-1
RM: message waiting failed with error 7.
В руководстве:
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
Маунал говорит, что для msgrcv () E2BIG получается, когда «длина текста сообщения больше, чем msgsz, а MSG_NOERROR не указан в msgflg.»
Но в моем случае, похоже, длина равна тексту сообщения. Кстати, как эта функция получит длину void * msgp? Это пустота.
Извините, я опубликовал длинный кусок кода, так как боюсь что-то пропустить.
Спасибо.
EDIT:
Руководство говорит,
The msgp argument is a pointer to caller-defined structure of the fol-
lowing general form:
struct msgbuf {
long mtype; /* message type, must be > 0 */
char mtext[1]; /* message data */
};
The mtext field is an array (or other structure) whose size is specified by msgsz, a non-negative integer value
Я добавил дополнительную информацию от gdb следующим образом:
227 RetVal = msgrcv (TDM_M [MyModule] .msg_id,
228 (void *) & SysMsg,
229 (size_t) sizeof (T_MSGBUF),
230 MsgType,
231 MsgFlag);
23
235 * /
(gdb) p sizeof (SysMsg)
10 долларов США = 1044
(gdb) p sizeof (T_MSGBUF)
11 долларов США = 1040
Length - Размер пункта назначения = 4 (= размер long int), похоже, что он правильный.
Кроме того, я обнаружил, что проблема происходит только с SunOS. Тот же код отлично работает в Linux.
Редактировать Я нашел основную причину. Подобно тому, как errno E2BIG, указывающее, что MsgLength меньше полученного сообщения, мой макрос отправки считает неправильное значение, которое должно было быть равно MsgLength в WAIT_MSG ().
Спасибо за ваш совет и ответы.
.h файл
/ * MSGBUF определен для конкретного сообщения
* SysMsg определяется как arg для msgrcv
* /
#define MSGBUF_SIZE 1040
#define MSGBODY_SIZE (MSGBUF_SIZE)
#define MSGBODY_SIZE1 (MSGBUF_SIZE-16)
typedef struct {
unsigned char SrcModule;
unsigned char DstModule;
unsigned char MsgType;
unsigned short SubMsgId;
unsigned short Length;
long int reserved;
} MsgHeader;
typedef struct _MsgBody {
unsigned char Data[MSGBODY_SIZE1];
} MSGBODY;
typedef struct _MsgBuf {
MsgHeader Header; // the header of message.
MSGBODY Body; // the message body.
} MSGBUF;
typedef struct _MsgInside {
long int MsgType;
MSGBUF MsgText;
} SYS_MSG;
.cpp
int WaitMsg (DMMODULE MyModule,
MSGBUF* pMsgBuf,
long MsgType,
int MsgFlag,
TIME_USEC abs_timeout)
{
SYS_MSG SysMsg;
int RetVal;
...
memset(&SysMsg, 0, sizeof(SYS_MSG));
printf("arguments:\n");
printf("MsgID: %d\n", Module[MyModule].msg_id);
printf("pointer: 0x%x\n", (void *)&SysMsg);
printf("sizeof: %d\n", (size_t)sizeof(T_MSGBUF));
printf("MsgType: %d\n", MsgType);
printf("MsgFlag: %d\n", MsgFlag);
/* Module is a global array in which msg_id is storing */
RetVal = msgrcv( Module [MyModule].msg_id,
(void *)&SysMsg,
(size_t)sizeof(MSGBUF),
MsgType,
MsgFlag);
/* So far, only ENOMSG is handled, the rest is ignored,
* Maybe a signal handler is needed later.
*/
if( RetVal == -1 )
{
switch (errno)
{
case ENOMSG:
return My_ENOMSG;
case E2BIG:
case EACCES:
case EAGAIN:
case EFAULT:
case EIDRM:
case EINTR:
case EINVAL:
/* Here is where the error reported */
printf("%s: message waiting failed with error %d.\n",
Module[MyModule].name, errno);
printf("%s: \n", strerror(errno));
return FAIL;
default:
printf("%s: message waiting failed with error %d.\n",
Module[MyModule].name, errno);
printf("%s: \n", strerror(errno));
return FAIL;
}
}
memcpy(pMsgBuf, &(SysMsg.MsgText), sizeof(T_MSGBUF));
printf("message is received by %s.\n", Module[MyModule].name);
return SUCC;
}
...
#define WAIT_MSG(MyModule,pMsgBuf,time_us ) \
WaitMsg((MyModule),(pMsgBuf),0,IPC_NOWAIT,0)
int main()
{
int rc = -1;
MSGBUF msgbuf;
rc = WAIT_MSG( RM, &msgbuf, 0 );
...
}
}