<p>C不支持直接序列化机制,因为在C中您无法在运行时获取类型信息。您必须自己在运行时注入一些类型信息,然后根据该类型信息构造所需的对象。因此,请定义所有可能的结构:</p>
<pre><code>typedef struct {
int myInt;
float myFloat;
unsigned char myData[MY_DATA_SIZE];
} MyStruct_1;
typedef struct {
unsigned char myUnsignedChar;
double myDouble;
} MyStruct_2;
</code></pre>
<p>然后定义enum,它收集关于您总共拥有哪些结构的信息:</p>
^{pr2}$
<p>定义帮助器函数,该函数用于确定任何结构大小:</p>
<pre><code>int GetStructSize(MyStructType structType) {
switch (structType) {
case ST_MYSTRUCT_1:
return sizeof(MyStruct_1);
case ST_MYSTRUCT_2:
return sizeof(MyStruct_2);
default:
// OOPS no such struct in our pocket
return 0;
}
}
</code></pre>
<p>然后定义序列化函数:</p>
<pre><code>void BinarySerialize(
MyStructType structType,
void * structPointer,
unsigned char * serializedData) {
int structSize = GetStructSize(structType);
if (structSize != 0) {
// copy struct metadata to serialized bytes
memcpy(serializedData, &structType, sizeof(structType));
// copy struct itself
memcpy(serializedData+sizeof(structType), structPointer, structSize);
}
}
</code></pre>
<p>和反序列化函数:</p>
<pre><code>void BinaryDeserialize(
MyStructType structTypeDestination,
void ** structPointer,
unsigned char * serializedData)
{
// get source struct type
MyStructType structTypeSource;
memcpy(&structTypeSource, serializedData, sizeof(structTypeSource));
// get source struct size
int structSize = GetStructSize(structTypeSource);
if (structTypeSource == structTypeDestination && structSize != 0) {
*structPointer = malloc(structSize);
memcpy(*structPointer, serializedData+sizeof(structTypeSource), structSize);
}
}
</code></pre>
<p>序列化用法示例:</p>
<pre><code>MyStruct_2 structInput = {0x69, 0.1};
MyStruct_1 * structOutput_1 = NULL;
MyStruct_2 * structOutput_2 = NULL;
unsigned char testSerializedData[SERIALIZED_DATA_MAX_SIZE] = {0};
// serialize structInput
BinarySerialize(ST_MYSTRUCT_2, &structInput, testSerializedData);
// try to de-serialize to something
BinaryDeserialize(ST_MYSTRUCT_1, &structOutput_1, testSerializedData);
BinaryDeserialize(ST_MYSTRUCT_2, &structOutput_2, testSerializedData);
// determine which object was de-serialized
// (plus you will get code-completion support about object members from IDE)
if (structOutput_1 != NULL) {
// do something with structOutput_1
free(structOutput_1);
}
else if (structOutput_2 != NULL) {
// do something with structOutput_2
free(structOutput_2);
}
</code></pre>
<p>我认为这是C语言中最简单的序列化方法,但它有一些问题:</p>
<ul>
<li>结构不能有指针,因为你永远不知道序列化指针时需要分配多少内存以及从何处/如何将数据序列化为指针。在</li>
<li>这个例子有系统endianess的问题-你需要注意如何在内存中存储数据-以big-endian或little-endian的方式,如果需要的话反转字节[将<code>char *</code>转换为整型,如<code>enum</code>](…或重构代码以使其更可移植)。在</li>
</ul>