如何使用函数指针序列化/反序列化结构 [英] How to serialize/deserialize structure with function pointer

查看:190
本文介绍了如何使用函数指针序列化/反序列化结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有人可以帮我解决如何用函数指针序列化/反序列化结构。

我已经声明了这样的函数指针类型:

typedef double(* myFunction)(double arg);

结束然后我想序列化/反序列化包含初始化myFunction类型变量的结构。

Hi, Can anyone please help me in how to serialize/deserialize structure with function pointer.
I have declared function pointer type like this:
typedef double(*myFunction)(double arg);
End then I want to serialize/deserialize structure that contains initialized myFunction type variable.

推荐答案

序列化C ++中的不同对象类型是通过注册表完成的。注册表通常是一个映射,其中键是以序列化形式表示对象的东西(例如对象类型的名称),值是可以重建对象的值,或者对象本身,如果我们是谈论一个常数。在函数指针的情况下,我们谈论的是一个常量,它可以在2个独立的程序启动之间进行更改(在重定位的情况下)但在单个启动终止对之间不会发生变化。在函数指针注册表的情况下,您使用唯一的id作为映射中的键(如name(字符串)或整数id),如果注册表包含具有不同签名的函数指针,则可以使用a(void *)作为值或者类型化的函数指针,如果注册表只包含相同类型的函数指针。



简单的愚蠢示例(VSC ++ 2010)将已注册的函数指针序列化为整数ID:

Serialization of different object types in C++ is done with registries. The registry is usually a map in which the key is something that represents the object in the serialized form (for example the name of the type of the object) and the value is something that can reconstruct the object, or the object itself if we are speaking about a constant. In case of a function pointer we are speaking about a constant that can change between 2 separate program startups (in case of relocation) but it doesn't change during between a single startup-termination pair. In case of function pointer registry you use a unique id as the key in the map (like name(string) or an integer id) and as a value you can use either a (void*) if the registry contains function pointers with different signatures or a typed function pointer if the registry contains only function pointers of the same type.

Simple stupid example (VSC++2010) that serializes registered function pointers as their integer IDs:
std::map<int,void*> g_IdToFuncPtr;
std::map<void*,int> g_FuncPtrToId;

template <typename FuncPtrType>
void RegisterFunc(FuncPtrType func)
{
    // check for duplicate registration
    assert(g_FuncPtrToId.find(func) == g_FuncPtrToId.end());
    int id = (int)g_IdToFuncPtr.size();
    g_IdToFuncPtr[id] = func;
    g_FuncPtrToId[func] = id;
}

template <typename FuncPtrType>
size_t Serialize(FuncPtrType func_ptr, void*& buf, const void* buf_end)
{
    if ((const char*)buf_end-(const char*)buf < sizeof(int))
        return 0;
    auto it = g_FuncPtrToId.find(func_ptr);
    assert(it != g_FuncPtrToId.end());
    if (it == g_FuncPtrToId.end())
        return 0;
    *(int*)buf = it->second;
    buf = (char*)buf + sizeof(int);
    return sizeof(int);
}

template <typename FuncPtrType>
size_t Deserialize(FuncPtrType& func_ptr, const void*& buf, const void* buf_end)
{
    if ((const char*)buf_end-(const char*)buf < sizeof(int))
        return 0;
    int id = *(int*)buf;
    auto it = g_IdToFuncPtr.find(id);
    if (it == g_IdToFuncPtr.end())
        return 0;
    func_ptr = (FuncPtrType)it->second;
    buf = (const char*)buf + sizeof(int);
    return sizeof(int);
}

void func1(int param)
{
}

void func2(int param)
{
}

void TestFuncSer()
{
    // filling registry
    RegisterFunc(func1);
    RegisterFunc(func2);

    typedef void (*TFuncType)(int);
    TFuncType func_ptr_variable = func1;
    TFuncType func_ptr_variable2 = func2;

    // serializing
    char buf[0x40];
    const void* buf_end = (buf + sizeof(buf));

    void* q = buf;
    size_t serialized_size = Serialize(func_ptr_variable, q, buf_end);
    size_t serialized_size2 = Serialize(func_ptr_variable2, q, buf_end);

    // deserializing
    const void* p = buf;
    TFuncType deserialized_func_ptr;
    TFuncType deserialized_func_ptr2;
    size_t deserialized_size = Deserialize(deserialized_func_ptr, p, q);
    size_t deserialized_size2 = Deserialize(deserialized_func_ptr2, p, q);
    printf("Done.\n");
}


你不能序列化/反序列化任何类型的指针...指向类,POD,void,函数,代码或任何东西的指针其他。由于程序的不同运行之间的某些地址可能不同,因此将指针值保存到文件存储是没有意义的。



对于函数的情况指针,你可能想要想出某种你想要映射的函数的枚举并存储那些信息。回读时,使用相同的表将枚举映射回函数指针。
You can't serialize/deserialize pointers of any kind ... pointers to classes, POD, void, functions, code or anything else. Since the address of something can differ between different runs of your program, it doesn't make sense to save a pointer value to file storage.

For the case of function pointers, you probably want to come up with some sort of enumeration of the function(s) you want mapped and store that information. When reading back, use the same table to map the enumeration back to the function pointer.


pasztorpisti,感谢您的解释和简单的示例代码)
pasztorpisti, thanks for your explanation and simple example code)


这篇关于如何使用函数指针序列化/反序列化结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆