Click here to Skip to main content
15,440,311 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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.
Posted

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:
C++
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");
}
 
Share this answer
 
v3
Comments
Sergey Alexandrovich Kryukov 5-Aug-13 14:46pm     CRLF
Good points, a 5. —SA
pasztorpisti 5-Aug-13 15:10pm     CRLF
Thank you! If the function pointers are used in the C++ program with other purpose than cooperation with plain C code then something is wrong...
H.Brydon 5-Aug-13 15:26pm     CRLF
This isn't really serialization. You are storing function pointers in a lookup table (okay a map) that are all used within one invocation of a program/executable. Serialization in the classic sense means storing something persistently while a program is running, terminating the program and recovering the data with a subsequent instance of the same or another program. It makes no sense to store pointer values across execution contexts (or in some cases, even threads). You are using a strained sense of "serialization" and I don't think answering OP's question. [update] Looking at the wikipedia definition of serialization at http://en.wikipedia.org/wiki/Serialization , it strengthens my point. It says: Serialization provides: - a method of persisting objects, for example writing their properties to a file on disk, or saving them to a database. - a method of remote procedure calls, e.g., as in SOAP. - a method for distributing objects, especially in software componentry such as COM, CORBA, etc. - a method for detecting changes in time-varying data. Your code example is interesting but does none of these things. It is not serialization. I said (above) that it "means storing something persistently ... (for a) subsequent instance of the same or another program" which is true, but it also includes marshalling across the network, to other systems, to other system types (and other things). I like your example (I might use it somewhere myself :-) ... but it does not marshall the function pointer data outside the current program's address space and despite the names you are using, it is not serializing or deserializing anything.
pasztorpisti 5-Aug-13 15:42pm     CRLF
Well, then what do you call it? :-) I'm afraid you confuse serialization with its use cases. Quoting the first few lines of the wiki page: "serialization is the process of translating data structures or object state into a format that can be stored (for example, in a file or memory buffer, or transmitted across a network connection link) and resurrected later in the same or another computer environment." My example is just a small part of a serialization framework, serialization of one specific type. The list you mentioned in your comment is a list of use cases of serialization frameworks. If you serialize function pointers with my serializer method then you can save them to database, send them as a soap message or corba message and then on the other side you can reconstruct the function pointers.
H.Brydon 5-Aug-13 18:20pm     CRLF
What do I call it (I assume you are asking what serialization is)? Serialization is the complete act of taking something (data, class, ...) and breaking down all of the pieces and sending somewhere. Generally in the context of applications, it is writing data for an app out to disk and deserialization is the converse, namely reading a data file into memory and building the resulting data structures. In my experience, the concept involves disassembling the pieces and doing some kind of I/O with them. The name "serialization" came from the idea of taking an object (including POD) and streaming it elsewhere through a serial line. A synonym for serialization is "data marshalling", which is used more frequently in COM and network apps. All of these serialization examples involve I/O, and logically moving the object/data from memory to "somewhere else". Mapping one piece of data to another place in memory is not serialization.
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.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 5-Aug-13 14:29pm     CRLF
Basically you are right about function pointers, not not about "pointers of any kind". Look, for example, for boost serialization... or .NET serialization (conceptually, in this context, CLI references are managed pointers, equivalent in this respect). —SA
pasztorpisti 5-Aug-13 14:41pm    
Why? A function pointer is just a constant. It can easily be handled with a simple registry (map) even if the value of this constant my change between program startups.
Sergey Alexandrovich Kryukov 5-Aug-13 14:46pm     CRLF
I'm not talking about a function pointer, Harvey did. But you are right. It actually depends on the purpose of this pointer. —SA
pasztorpisti 5-Aug-13 14:51pm    
I wasn't careful when reading this answer anyway, the answer about enumeration/funcptr stuff is okay. :-)
H.Brydon 5-Aug-13 15:59pm     CRLF
Actually OP did (the way I read the question)... but see my replies to pasztorpisti. In any case, OP flagged his solution as the answer. I'll give +5 to his solution.
pasztorpisti, thanks for your explanation and simple example code)
 
Share this answer
 
Comments
pasztorpisti 5-Aug-13 15:56pm    
You are welcome!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900