使用mmap序列化复杂对象

时间:2014-07-30 07:16:35

标签: c++

我想在C ++中使用mmap将复杂对象序列化为二进制文件。复杂对象是指包含指针的对象(如树数据结构)。

我的想法是能够以这种方式使用mmap从文件中加载对象:

my_structure obj = (my_structure)mmap(...)

无需重新加载所有数据结构,以达到性能目的(因为它是一个庞大的数据结构!)。 我在互联网上找到的所有例子都非常简单(比如如何将int放入文件......)而且我找不到关于如何编写与包含pointeurs的对象相对应的内存的任何内容?我们怎么能这样做?

注意:我在mac osx上

2 个答案:

答案 0 :(得分:0)

有一种有趣的方式,我已经看到它,但它的使用是有限的:

首先,您无法序列化指针或任何其他非POD类型。使用指针引用序列化结构的方法是使用一种特殊类型,而不是保持指针值保持与其内存位置的偏移量:

示例:

struct void_ptr
{
    int     offset;

    void * get ()
    {
        return ((char*)this) + offset;
    }
};

//or for generic type:

template <class T>
struct t_ptr
{
    int     offset;

    T * get ()
    {
        return (T*)(((char*)this) + offset);
    }
};

其次,你需要一个特殊的序列化器来计算类/结构中所有成员的偏移量

让我们举个例子,你想序列化struct A:

struct A
{
    t_ptr<int>  pointer_to_int;//let's suppose it points to an array of 2 ints      
    int         my_value;
};

此结构的总内存需求为16个字节或4个整数(my_value为1个,pointer_to_int偏移为1个,int指向的int数组指针为2个) pointer_to_int指向的数组需要在结构内存数据和int_ptr的偏移量之后立即位于内存中,因为

示例:

int m[] = { 8, 1, 2, 3 };

A& a = *(A*)&m[0];

std::cout << a.my_value << std::endl;
std::cout << a.pointer_to_int.get()[0] << std::endl;
std::cout << a.pointer_to_int.get()[1] << std::endl;

在做这样的事情时知道并处理内存对齐非常重要!!!

答案 1 :(得分:0)

你要做的事情在C ++中是危险的。将指针或引用作为成员失败就足够了,因为在反序列化时你将无法恢复它们。您将无法直接恢复指针,因为数据地址在运行之间会发生变化。

很可能你想查看以下页面:

您可能还需要对程序进行重组,这样对于序列化数据,您不要将指针用作成员,因为大多数库为您指定了合适的可序列化数据结构:它们自己生成的类或纯数据的组合和STL。

根据数据的性质,您可能希望拆分或分块数据。