我需要发送一些关于VxWorks消息队列的信息。要发送的信息是在运行时决定的,可能是不同的数据类型。我使用了一个结构-
struct structData
{
char m_chType; // variable to indicate the data type - long, float or string
long m_lData; // variable to hold long value
float m_fData; // variable to hold float value
string m_strData; // variable to hold string value
};
我当前正在通过消息队列发送structData数组。
structData arrStruct[MAX_SIZE];
这里的问题是结构中一次只有一个变量是有用的,另外两个是无用的。因此消息队列不必要地过载。我不能使用联合,因为数据类型和值是必需的。我尝试使用模板,但它不能解决问题。我一次只能发送一个数据类型的结构数组。
template <typename T>
struct structData
{
char m_chType;
T m_Data;
}
structData<int> arrStruct[MAX_SIZE];
是否有保存此类信息的标准方法?
6条答案
按热度按时间a8jjtwal1#
我不明白你为什么不能用工会。这是标准的方式:
通常情况下,您打开数据类型,然后访问对该类型有效的字段。
请注意,您不能将
string
放入联合体中,因为string
类型是非POD类型。我已将其更改为使用指针,该指针可以是C中以零结尾的字符串。然后,您必须考虑根据需要分配和删除字符串数据的可能性。4smxwvx52#
您可以使用boost::variant来实现这一点。
nfg76nw03#
有很多方法可以处理不同的数据类型。除了联合解决方案之外,您还可以使用如下通用结构:
这样你就知道了类型,你就可以把void* 指针转换成正确的类型。这就像联合解决方案,一种更像C而不是C的做事方式。C的方式是使用继承。你定义一个基类“Data”,使用继承来专门化数据。如果需要的话,你可以使用RTTI来检查类型。
但正如你所说,你需要通过VxWorks队列发送数据。我不是Maven,但如果这些队列是操作系统实时队列,所有以前的解决方案都不是好的。你的问题是,你的数据有可变长度(特别是字符串),你需要通过一个队列发送它们,可能会要求像固定长度的数据结构和这个数据结构的实际长度。
根据我的经验,正确的处理方法是将数据序列化为类似于缓冲区类/结构的东西,这样可以优化大小(只序列化需要的内容),并且可以通过队列发送缓冲区。
为了序列化,你可以使用像1字节的类型,然后数据。为了处理可变长度的数据,你可以使用1到n字节来编码数据长度,这样你就可以反序列化数据。
对于字符串:1字节编码类型(0x 01 =字符串,...)2字节编码字符串长度(如果需要小于65536字节)n数据字节
因此,字符串“Hello”将被序列化为:
你需要一个缓冲器类和一个序列化器/反序列化器类。然后你做一些类似的事情:
而在另一边
我希望这有帮助,而且我没有误解你的问题。如果VxWorks队列不是我想的那样,序列化部分就大材小用了。
yv5phkfx4#
要非常小心消息队列中的“string”成员,它是一个指针,指向包含实际字符串字符的malloc内存,所以你只是在队列中传递“指针”,而不是真实的的字符串。
接收进程可能无法访问字符串内存,或者更糟的是,在消息阅读器试图获取它时,它可能已经被破坏了。
7uhlpewt5#
+1为1800和Ylisar。
利用工会来处理这类事情可能是一条可行之路。但是,正如其他人所指出的,它有几个缺点:
因此,除非您可以构建一个很好的 Package 器,否则使用boost::variant的方式可能更安全。
这有点离题,但这个问题是ML家族语言具有如此强大吸引力的原因之一(至少对我来说)。例如,您的问题在OCaml中得到了优雅的解决:
flvtvl506#
在Qt中尝试Qvariant