How to add n bytes in 64 bit system
I am working in 64 bit x_86 64 bit OSX system.
I am 开发者_如何学JAVAreading the file of legacy database. It is loaded to a memory block and using offsets it read to the structures. It is written in 32 bit mode.
So in order to read properly in 64 bit mode, I want to add n bytes to the base address of a structure.
Since pointer incement
increment does not help me to do it As it is in 64 bit mode every pointer is b byte long.
Regards, Dhana.
I have posted some code here. I guess it is right..
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);
}
I recommend instead that you read the file from disk using functions that you write such as read_uint32_whatever_endian(FILE*)
and such, and store these in your new 64bit in-memory struct
s.
This insulates your new code from the choices the compiler makes about the memory layout of your structures.
On a modern machine, the performance cost of such parsing is so minimal that I am sure you can hardly measure it.
Whilst there is a slight corner-case where nmap
ed large database files that store the same binary structure as the compiler's in-memory representation is a plus, this case is not worth much in practice.
The benefits of a different serialisation on disk to in memory provide plenty of practical pluses:
- it's portable - you can run your code on different processors with different word-sizes and different endians without issues
- you can extend the structures at any time - you could make the in-memory structures into objects with methods and such, even virtual C++ methods, and other benefits of object oriented design; you can also add members that don't get serialised, such as pointers and other fields, and you can support new database file versions easily
In order to advance a pointer by something other than it's native size, you have to cast to char *.
To read from a file that uses 32 bit values as "pointers" using a 64 bit processor, you have to redefine your structures so that fields that used to be pointers are still 32 bits in size.
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);
精彩评论