Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C是否相当于python pickle(对象序列化)?_Python_C_Client_Pickle - Fatal编程技术网

C是否相当于python pickle(对象序列化)?

C是否相当于python pickle(对象序列化)?,python,c,client,pickle,Python,C,Client,Pickle,这个python代码的C等价物是什么? 谢谢 data = gather_me_some_data() # where data = [ (metic, datapoints), ... ] # and datapoints = [ (timestamp, value), ... ] serialized_data = cPickle.dumps(data, protocol=-1) length_prefix = struct.pack("!L", len(serialized_data))

这个python代码的C等价物是什么? 谢谢

data = gather_me_some_data()
# where data = [ (metic, datapoints), ... ]
# and datapoints = [ (timestamp, value), ... ]

serialized_data = cPickle.dumps(data, protocol=-1)
length_prefix = struct.pack("!L", len(serialized_data))
message = length_prefix + serialized_data

如果您可以使用C++,则

C不支持直接序列化机制,因为在C中不能在运行时获取类型信息。您必须自己在运行时注入一些类型信息,然后根据该类型信息构造所需的对象。因此,请定义所有可能的结构:

typedef struct {
  int myInt;
  float myFloat;
  unsigned char myData[MY_DATA_SIZE];
} MyStruct_1;

typedef struct {
  unsigned char myUnsignedChar;
  double myDouble;
} MyStruct_2;
然后定义枚举,该枚举收集有关您总共拥有的结构的信息:

typedef enum {
  ST_MYSTRUCT_1,
  ST_MYSTRUCT_2
} MyStructType;
定义用于确定任何结构大小的辅助函数:

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;
      }
}
然后定义序列化函数:

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);
  }
}
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);
    }
}
和反序列化功能:

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);
  }
}
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);
    }
}
序列化用法示例:

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);
}
我认为这是C中最简单的序列化方法。但它有一些问题:

  • 结构不能有指针,因为您永远不知道序列化指针时需要分配多少内存,以及从何处/如何将数据序列化为指针
  • 此示例存在系统端性问题—您需要注意数据在内存中的存储方式—以大端或小端的方式,并在需要时反转字节[将
    char*
    强制转换为整数类型,例如
    enum
    ](…或重构代码以使其更便于移植)

我希望您知道Python的
pickle
cPickle
模块。如果这是一个学习练习,那就好了。但如果不是,你应该知道,有一百万种类似的东西(谷歌协议缓冲区、节俭等等)经过了很好的测试。我知道安全问题,是的,这不是一个完整的学习练习,但是在花了一整天的时间在谷歌上写上面的代码之后,这肯定会成为一种学习活动我还没有找到任何能给我指明正确方向的东西。我不确定上面的代码有两件事。1) 我做的“泡菜倾倒”正确吗??2) 我想我需要在发送到服务器之前序列化数据(类似于perl pack()函数)??链接到实现我想要的功能的示例C代码将是一个巨大的帮助。:)投票以“不是问题”结束,因为你实际上没有在问题中提出问题。此外,你评论中的问题似乎相当广泛,而且是以讨论为导向的,StackOverflow试图避免这些问题。在Python中,消息是否会被取消勾选?您想在不使用C中的cPickle模块的情况下执行此操作吗?问题不是如何在C中序列化对象,而是如何以pickle格式呈现C结构。这并不能回答问题。