如何在特定内存位置创建大小可变的 class 实例?
How do I create an instance of a class, variably sized, at a specific memory location?
我正在从事一个涉及将数据包写入内存映射文件的项目。我们目前的策略是创建一个包含以下成员
的数据包class
uint32_t packetHeader;
uint8_t packetPayload[];
uint32_t packetChecksum;
当我们创建一个数据包时,首先我们希望它在内存中的地址是内存映射文件中指定的偏移量,我认为这可以通过placement-new()
来完成。但是,我们还希望 packetPayload
不是指向堆中某些内存的指针,而是与 class 的其余部分连续(这样我们就可以避免 memcpy
ing 来自堆到我们最终的输出文件)
即
Memory
Beginning of class | BOC + 4 | (length of Payload) |
Header Payload Checksum
使用 Packet class 构造函数的 length
参数可以实现吗?或者我们是否必须将此 class 模板化为可变大小的有效载荷?
首先请记住,您需要以某种方式知道有效载荷的长度。您可以在实例中的某个地方指定它,或者在有效负载长度上模板化 class。
话虽如此 - 您将需要以下之一:
- packetOffset 是一个指针
- 有效负载长度成员
- 校验和偏移成员
并且您需要使用一个 named constructor idiom 来获取分配长度,并将 offset/length/pointer 成员的分配和设置都执行到与该长度相对应的值。
忘记尝试使它成为您 class 的布局。您将整天与 C++ 语言作斗争。而是 class 提供对二进制布局(在共享内存中)的访问。但是 class 实例本身不会在共享内存中。而shared/mapped内存中的字节范围根本不会是C++对象,它只是存在于文件映射地址范围内。
想必长度从创建的那一刻起就固定了?如果是这样,那么您可以安全地将长度、指向校验和的指针等缓存在访问器对象中。由于此缓存不在文件内,因此您可以随心所欲地存储任何内容,而无需担心其布局。您甚至可以使用虚拟成员函数,因为 v-table 将进入 class 实例,而不是二进制文件的范围。
此外,考虑到它存在于共享内存中,如果有多个编写器,您必须非常小心地在它们之间进行同步。如果您只是在 shared/mapped 内存中预先放置一个缓冲区以避免以后复制,但完全移交进程之间的所有权,以便数据永远不会被同时访问共享,那么它会更容易。您可能还想在写入所有数据后计算一次校验和,而不是尝试为每次写入缓冲区保留它 up-to-date(并冒着数据竞争的风险)。
我正在从事一个涉及将数据包写入内存映射文件的项目。我们目前的策略是创建一个包含以下成员
的数据包classuint32_t packetHeader;
uint8_t packetPayload[];
uint32_t packetChecksum;
当我们创建一个数据包时,首先我们希望它在内存中的地址是内存映射文件中指定的偏移量,我认为这可以通过placement-new()
来完成。但是,我们还希望 packetPayload
不是指向堆中某些内存的指针,而是与 class 的其余部分连续(这样我们就可以避免 memcpy
ing 来自堆到我们最终的输出文件)
即
Memory
Beginning of class | BOC + 4 | (length of Payload) |
Header Payload Checksum
使用 Packet class 构造函数的 length
参数可以实现吗?或者我们是否必须将此 class 模板化为可变大小的有效载荷?
首先请记住,您需要以某种方式知道有效载荷的长度。您可以在实例中的某个地方指定它,或者在有效负载长度上模板化 class。
话虽如此 - 您将需要以下之一:
- packetOffset 是一个指针
- 有效负载长度成员
- 校验和偏移成员
并且您需要使用一个 named constructor idiom 来获取分配长度,并将 offset/length/pointer 成员的分配和设置都执行到与该长度相对应的值。
忘记尝试使它成为您 class 的布局。您将整天与 C++ 语言作斗争。而是 class 提供对二进制布局(在共享内存中)的访问。但是 class 实例本身不会在共享内存中。而shared/mapped内存中的字节范围根本不会是C++对象,它只是存在于文件映射地址范围内。
想必长度从创建的那一刻起就固定了?如果是这样,那么您可以安全地将长度、指向校验和的指针等缓存在访问器对象中。由于此缓存不在文件内,因此您可以随心所欲地存储任何内容,而无需担心其布局。您甚至可以使用虚拟成员函数,因为 v-table 将进入 class 实例,而不是二进制文件的范围。
此外,考虑到它存在于共享内存中,如果有多个编写器,您必须非常小心地在它们之间进行同步。如果您只是在 shared/mapped 内存中预先放置一个缓冲区以避免以后复制,但完全移交进程之间的所有权,以便数据永远不会被同时访问共享,那么它会更容易。您可能还想在写入所有数据后计算一次校验和,而不是尝试为每次写入缓冲区保留它 up-to-date(并冒着数据竞争的风险)。