如何在64位系统中添加n个字节
-
20-09-2019 - |
题
我在64位X_86 64位OSX系统中工作。
我正在阅读旧数据库的文件。它已加载到存储块并使用其读取到结构的偏移。它以32位模式编写。
因此,为了在64位模式下正确读取,我想在结构的基础地址中添加n个字节。
由于指针碰巧
增量无助于我做到这一点,因为它处于64位模式下,每个指针都是B字节长的。
问候,达纳。
我在这里发布了一些代码。我想这是对的..
struct CamNodeTag {
CamNodeTag *nextCam; // next cam
SInt32 numMake;
char *menuMake;
};
long pBaseAddr; // this is long so we an offset bytes from it.
//Get the size of of the structure in 32 bit environment.//in 64 bit envi it is 20 bytes.
int CamNodeTagSizeIn32BitMode = 12;
//Do it in a while loop..
int i=0;
CamNodeTag * pNode = (CamNodeTag *)(pBaseAddr + i*CamNodeTagSizeIn32BitMode);
while(pNode !=NULL)
{
//Do the cam stuff here..
// to get the next node, we add the base addr to the offset
//This will give next cam
i++;
pNode = (CamNodeTag *)(pBaseAddr + i*CamNodeTagSizeIn32BitMode);
}
解决方案
我 推荐 您使用您写的函数从磁盘中读取文件,例如 read_uint32_whatever_endian(FILE*)
等等,并将其存储在您的新64位内存中 struct
s。
这使您的新代码从编译器对结构的内存布局做出的选择中绝缘。
在现代机器上,这种解析的性能成本是如此最小,以至于我敢肯定您几乎无法衡量它。
有一个 轻微 拐角处的地方 nmap
ED大型数据库文件存储与编译器的内存表示相同的二进制结构是一个加号,这种情况在实践中不值得。
在记忆中,磁盘上不同序列化的好处提供了许多实用的优势:
- 它是便携式的 - 您可以在不同的单词尺寸和不同的endians的不同处理器上运行代码,而没有问题
- 您可以随时扩展结构 - 您可以将内存结构制作到使用方法等,甚至虚拟C ++方法以及面向对象设计的其他好处;您还可以添加不会序列化的成员,例如指针和其他字段,并且可以轻松支持新的数据库文件版本
其他提示
为了通过除本地大小以外的其他东西来推进指针,您必须施放到char *。
要从使用32位值用作“指针”的文件中读取使用64位处理器的“指针”,您必须重新定义结构,以便以前是指示器的字段仍然是32位的大小。
typedef int Off32; // our "pointers" need to be 32 bit ints rather than pointers.
struct CamNodeTag {
Off32 nextCam; // next cam
SInt32 numMake;
Off32 menuMake;
};
char * pBaseAddr; // this is char * so we an offset bytes from it.
// set this to point to the first node.
CamNodeTag * pNode = (CamNodeTag *)(pBaseAddr + first_node_offset);
// to get the next node, we add the base addr to the offset
// in the structure.
pNode = (CamNodeTag *)(pBaseAddr + pNode->nextCam);
// assuming that the menuMake pointer is also an offset from the base
// use this code to get the actual pointer.
//
char * pMenu = (pBaseAddr + pNode->menuMake);
不隶属于 StackOverflow