取消引用结构联合的结构
typedef struct
{
int data1;
float data2;
} packetType1;
typedef struct
{
bool data1;
} packetType2;
typedef union
{
packetType1 p1;
packetType2 p2;
} packet;
struct
{
int type;
packet myPacket;
} message;
现在我创建一条消息并将指向该消息的指针传递给一个函数。在这个函数中,我需要取消引用该消息并从中取出必要的数据。
该数据将取决于数据包是否填充有 packetType1 类型或 packetType2 类型的数据。 message 内部,整型变量 type 只能包含值 1 或 2,表示 message 内的数据包是 packetType1 类型还是 packetType2 类型。
我想知道这样做是否安全 -
packetType1 s1;
s1.data1 = 10;
s1.data2 = 22.22;
packetType2 s2;
s2.data1 = true;
packet pack1;
pack1.p1 = s1;
packet pack2;
pack2.p2 = s2;
message m1;
m1.type = 1;
m1.myPacket = pack1;
message m2;
m2.type = 2;
m2.myPacket = pack2;
eatPacket( &m1 );
eatPacket( &m2 );
void eatPacket( void *p )
{
if( *(int*)p == 1)
{
message msg = *(message*)p
cout << msg.myPacket.data1;
cout << msg.myPacket.data2;
}
else if( *(int*)p == 2)
{
message msg = *(message*)p
cout << msg.myPacket.data1;
}
}
编辑:(对于所有询问我为什么使用 void* 的人)
这些消息使用 posix 消息队列从一个进程发送到另一个进程,然后进行解码那里。问题是,即使这个消息结构也可能不同。我唯一确定的是变量 int 类型将永远在那里指导我。消息的其他部分可能会发生变化。因此,我必须通过使其接受 void * 来使其通用,然后使用变量类型提供的值进行内部解码。
考虑一下现在有人发出这样的消息 -
struct
{
int type;
float data;
bool moreData;
int evenMoreData;
} newMessage;
对于这个新消息,变量类型的值将始终为 3。
因此,在我的 eat 函数中,我将添加另一个像这样的子句
if( *(int*)p == 3)
{
newMessage msg = *(newMessage*)p
cout << msg.data;
cout << msg.moreData;
cout << msg.evenMoreData;
}
这样做仍然安全吗?我希望现在这有意义吗?
typedef struct
{
int data1;
float data2;
} packetType1;
typedef struct
{
bool data1;
} packetType2;
typedef union
{
packetType1 p1;
packetType2 p2;
} packet;
struct
{
int type;
packet myPacket;
} message;
Now I make a message and pass the pointer to this message to a function. Inside this function I need to de-reference the message and take out the necessary data from it.
This data will depend on whether packet was filled with data of packetType1 type or of packetType2 type. Inside message , the integer variable type can contain the value 1 or 2 only, telling that packet inside message is of type packetType1 or of type packetType2.
I want to know if this is safe to do -
packetType1 s1;
s1.data1 = 10;
s1.data2 = 22.22;
packetType2 s2;
s2.data1 = true;
packet pack1;
pack1.p1 = s1;
packet pack2;
pack2.p2 = s2;
message m1;
m1.type = 1;
m1.myPacket = pack1;
message m2;
m2.type = 2;
m2.myPacket = pack2;
eatPacket( &m1 );
eatPacket( &m2 );
void eatPacket( void *p )
{
if( *(int*)p == 1)
{
message msg = *(message*)p
cout << msg.myPacket.data1;
cout << msg.myPacket.data2;
}
else if( *(int*)p == 2)
{
message msg = *(message*)p
cout << msg.myPacket.data1;
}
}
Edit: ( For all those who are asking why I had used void* )
These messages are sent from one process to other using posix message queue and then decoded there. Problem is that even this message structure could be different. Only thing I am sure is that the variable int type will always be there to guide me. Other part of the message might change. So I had to make this function generic by making it accept a void * and then do decoding internally using the value provided by variable type.
Consider that someone makes a message like this now-
struct
{
int type;
float data;
bool moreData;
int evenMoreData;
} newMessage;
For this new message it was decided that value for variable type would always be 3.
So in my eat function I will just add another clause like this
if( *(int*)p == 3)
{
newMessage msg = *(newMessage*)p
cout << msg.data;
cout << msg.moreData;
cout << msg.evenMoreData;
}
Will it still be safe to do so ? I hope this makes sense now ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
看起来不错,但我会像这样重写
eatPacket()
:我确实不需要我能看到的
void*
体操。如果您确实需要msg
作为指针,您可以以简单的方式修改上面的内容(->
表示.
等)。It looks fine, but I'd rewrite
eatPacket()
like this:There's really no need for the
void*
gymnastics that I can see. If you really needmsg
to be a pointer you can modify the above in a straightforward way (->
for.
, etc).我该怎么办?
按照你的方式安全吗?我真的不知道。什么是消息?
What would I do?
Is it safe to do your way? I don't really know. What is message?
我不会做这些事。我认为创建一个抽象 BaseMessage 类,然后派生一个用于 int 有效负载的类和一个用于 bool 有效负载的类会更清晰。然后你就可以有一个虚拟的 GetData() 方法。当您将指针传递给基类时,将调用正确的虚函数来返回数据。联合几乎总是一种代码异味,面向对象技术可以帮助解决。我实际上如何实现这一点很大程度上取决于消息的种类以及它们最终如何使用,但希望您能理解。
I wouldn't do any of this. I would think it would be much cleaner to create an abstract BaseMessage class and then derive a class for the int payload and one for the bool payload. Then you could have a virtual GetData() method. When you pass in the pointer to the base class the correct virtual function will get invoked to return your data. A union is almost always a code smell that OO techniques can help with. A lot of how I would actually implement this depends on the variety of messages and how they eventually get used but hopefully you get the idea.