我正在尝试序列化像下面这样的简单单级类,没有像 boost 这样的外部库,也不必为每个类实现序列化器函数。尽管我的类很少,我可以轻松地为每个类实现一个序列化程序,但为了将来参考,我希望手头有一个可以很好地扩展的简单解决方案。
每个类被序列化的要求是它的成员只能是可序列化的类型,并且定义了一个成员指针数组,这样在序列化时,无论传递哪个类,都可以迭代成员。
问题是编译失败是因为缺少成员指针被取消引用的强制转换,显然:
esp32.ino: 122:35: error: 'footprint.MessageFootprint<1>::Members[i]' 不能用作成员指针,因为它的类型是 'void*
我不知道如何将成员指针存储在可迭代集合中或如何避免强制转换void*
。这就是我的目标。我想在具有单个通用序列化函数的序列化时迭代类成员。我不知道该怎么办。
enum SerializableDataTypes {
SerInt,
SerFloat,
SerString,
SerIntArray
};
template <int N>
struct MessageFootprint {
SerializableDataTypes DataTypes[N];
void* Members[N];
};
template<typename T, typename R>
void* void_cast(R(T::*m))
{
union
{
R(T::*pm);
void* p;
};
pm = m;
return p;
}
class ControlMessage{};
// first structure to be serialized
class Message1 : public ControlMessage {
public:
int prop1;
int prop2;
};
const int Message1MemberCount = 2;
const MessageFootprint<Message1MemberCount> Message1FootPrint = { { SerInt, SerInt }, {void_cast(&Message1::prop1), void_cast(&Message1::prop2)} };
// second structure to be serialized
class Message2 : public ControlMessage {
public:
int prop1;
String prop2;
};
const int Message2MemberCount = 2;
const MessageFootprint<Message2MemberCount> Message2FootPrint = { { SerInt, SerInt }, {void_cast(&Message2::prop1), void_cast(&Message2::prop2)} };
template<int N>
void SerializeMessage(MessageFootprint<N> footprint, ControlMessage message) {
for (int i = 0; i < N; i++) {
if (footprint.DataTypes[i] == SerInt) {
// serialization code here based on data type
// for demonstration purposes it's only written in the serial port
logLine(String(i));
Serial.println(*((int*)(message.*(footprint.Members[i]))));
}
}
}
void main() {
// usage example
Message1 msg = Message1();
msg.prop1 = 1;
msg.prop2 = 2;
SerializeMessage(Message1FootPrint, msg);
}