我正在一个项目中,涉及将数据包写入内存映射文件。我们当前的策略是创建一个包含以下成员的数据包类
uint32_t packetHeader;
uint8_t packetPayload[];
uint32_t packetChecksum;
当我们创建一个数据包时,首先我们希望将其在内存中的地址设置为内存映射文件中的指定偏移量,我认为这可以通过Placement-new()
完成。但是,我们也希望packetPayload
不能成为堆中某些内存的指针,而应与该类的其余部分相连(因此,我们可以避免memcpy
从堆到最终对象)。输出文件)
即
Memory
Beginning of class | BOC + 4 | (length of Payload) |
Header Payload Checksum
使用Packet类构造函数的length
参数是否可以实现?还是我们必须为可变大小的有效载荷模板此类?
答案 0 :(得分:1)
忘了尝试使您的班级布局成为现实。您将全天与C ++语言作斗争。而是提供访问二进制布局(在共享内存中)的类。但是类实例本身将不在共享内存中。共享/映射内存中的字节范围根本不是C ++对象,它仅存在于文件映射地址范围之内。
大概长度从创建之时起就固定了吗?如果是这样,则可以安全地将长度,指向校验和的指针等缓存在访问器对象中。由于此缓存不在文件内部,因此您可以存储所需的任何内容,而无需担心其布局。您甚至可以使用虚拟成员函数,因为v表在类实例中而不是二进制文件的范围中。
此外,鉴于这存在于共享内存中,因此如果有多个编写器,则必须非常小心地在它们之间进行同步。如果您只是在共享/映射的内存中预先放置一个缓冲区以避免以后再复制,而是完全在进程之间移交所有权,以使数据不会被同时访问所共享,那么它将变得更加容易。您可能还希望在所有数据写入后计算一次校验和,而不是尝试对每次向缓冲区中的每次写入都保持最新(并在过程中冒数据竞争的风险)。
答案 1 :(得分:0)
首先请记住,您需要以某种方式知道有效载荷的长度。您可以在实例的某个位置指定它,也可以在有效负载长度上为类创建模板。
话虽如此-您将需要以下之一:
您将要使用一个named constructor idiom,它采用分配长度,并将偏移量/长度/指针成员的分配和设置都执行为与长度相对应的值。