【发布时间】:2020-04-21 21:47:04
【问题描述】:
我有几个包含各种参数组合的结构。我编写了一个函数,该函数采用对结构的 void 指针引用(有几种不同的类型),并将数据参数中的信息写入其中。下面是函数:
void SubModelBase::writeDataStruct(byte msgID, void *ptr, QByteArray data)
{
*(byte*)ptr[0] = msgID;
*(byte*)ptr[1] = data.length();
for (int i = 2; i < data.length(); i++)
{
*(byte*)ptr[i] = data.at(i);
}
}
void *ptr 是对我想要写入数据的结构的引用,但我在延迟指针时遇到了问题,因此我可以写入它。我确定我只是在这里的语法中遗漏了一些愚蠢的东西,但我现在没有看到它......
编辑:
好的,我重写了函数,在赋值之前先将 void 指针转换为字节指针:
void SubModelBase::writeDataStruct(byte msgID, void *ptr, QByteArray data)
{
byte* structData = (byte*)ptr;
structData[0] = msgID;
structData[1] = data.length();
for (int i = 0; i < data.length(); i++)
{
structData[i + 2] = data.at(i);
}
}
尚未测试,但现在至少可以编译。我这样做是因为有超过 30-40 个不同的结构需要在其中填充数据,我需要一个可以轻松处理操作的函数,而无需了解每个结构的详细信息。但是,如果有更好的方法来解决这个问题,我绝对愿意接受。
编辑 2: 修复循环中的逻辑错误
【问题讨论】:
-
我认为通过投影到字节数组来写入结构不是一个好主意。我建议根据一些调度参数(
msgID?)将ptr转换为指向特定结构的指针。 -
您不能取消引用 void 指针。您必须先将它们转换为实际类型。这是否意味着类似于
memcpy? -
您不能通过
byte*写入结构。您需要转换为适当的类型。 (这不仅仅是你缺少的一些愚蠢的语法,它是关于语义和类型的重要和基本的东西。) -
@DanielsaysreinstateMonica 假设
ptr从未被实际声明为特定的结构类型(例如,说它是char buffer[256]或其他一些结构,如DataPacket)并不会带来对齐问题的风险,别名等等? -
这里的结构体类型到底是什么,你想达到什么目的?您想获取一些结构,将其转换为文件/网络 IO 的字节,然后再次安全地转换回来吗?为什么跳过
data.at(0)和data.at(1)?