是否可以使用具有指向内存映射文件中另一个结构的指针的结构,而不是将偏移量存储为某种整数类型并计算指针?
例如给出以下结构:
typedef struct _myStruct_t {
int number;
struct _myStruct_t *next;
} myStruct_t;
myStruct_t* first = (myStruct_t*)mapViewHandle;
myStruct_t* next = first->next;
代替此:
typedef struct _myStruct_t {
int number;
int next;
} myStruct_t;
myStruct_t* first = (myStruct_t*)mappedFileHandle;
myStruct_t* next = (myStruct_t*)(mappedFileHandle+first->next);
我读过有关'__based'关键字,但这是Microsoft特定的,因此与Windows绑定。
正在寻找使用GCC编译器的工具。
我很确定没有什么类似于GCC中Visual Studio中的__based
指针。我唯一看到过类似内置功能的地方是在一些非常奇怪的硬件上。 Visual Studio扩展提供了围绕涉及指针的所有操作的地址转换层。
因此,听起来您正在进入自己的领土;尽管我愿意被告知其他情况。
我上次处理这样的事情是在掌上平台上,除非您锁定内存,否则它可能会四处移动。您从分配中获得了内存句柄,在使用完它之前必须先到MemHandleLock
,在使用完之后必须先到MemPtrUnlock
,以便该块可以被OS移动(这似乎发生在基于ARM的Palm设备上) 。
如果您坚持将指针式的值存储在内存映射的结构中,则第一个建议是将值存储在intptr_t
中,该值是可以包含指针值的int大小。虽然您的偏移量不太可能超过4GB,但为了安全起见,这是值得的。
也就是说,这很容易使用模板类在C ++中实现,只是将问题标记为C会使事情变得更加混乱。
第一个极不可能工作。
请记住,诸如struct _myStruct_t *
之类的指针是指向位置在内存中]的指针。假设此结构位于内存中的地址1000
:这意味着紧随其后的下一个结构可能位于地址1008
,这就是存储在->next
中的内容(数字不重要;重要的是它们是内存地址)。现在,您将该结构保存到文件中(或取消映射)。然后再次映射它,但是这次,它最终从地址2000
开始,但是->next
指针仍然是1008
。
您(通常)无法控制文件在内存中的映射位置,因此无法控制映射结构中元素的实际存储位置。因此,您可以only
取决于相对偏移量。请注意,根据mappedFileHandle
的声明类型,您的第二个版本可能无法正常工作。如果它是指向myStruct_t
的指针,则向其添加整数n
将生成一个指向内存中的地址的指针,该地址比存储空间中的n*sizeof(myStruct_t)
字节高n
字节。
如果您声明mappedFileHandle
为
myStruct_t* mappedFileHandle;
然后您可以将其下标为数组。如果将映射文件布置为
myStruct_t
块的序列,并且next
字段按该序列内的索引引用其他块,则(假设myStruct_t* b
是感兴趣的块)
mappedFileHandle[b->next].number
是序列中第
number
个块的b->next
字段。
(这只是在C中定义数组的方式的结果:mappedFileHandle[b->next]
被定义为等效于*(mappedFileHandle + b->next)
,这是myStruct_t
类型的对象,因此可以得到number
的字段。
C ++:这是非常可行且可移植的(代码,但可能不是数据)。不久前,但是我为自相关指针类创建了一个模板。我在可能移动的内存块中有树结构。在内部,该类具有单个intptr_t,但= *。 ->运算符已重载,因此它看起来像常规指针。处理null引起了一些注意。我还使用int,short和不太有用的char进行了版本处理,这些char对于无法指向较远空间的指针(外部内存块)。