Come aggiungere n byte a 64 bit del sistema
-
20-09-2019 - |
Domanda
Sto lavorando nel sistema di OSX 64 bit x_86 64 bit.
Sto leggendo il file di database legacy. E 'caricato a un blocco di memoria e l'utilizzo di offset farlo leggere alle strutture. E 'scritto in modalità a 32 bit.
Quindi, al fine di leggere correttamente in modalità a 64 bit, Voglio aggiungere n byte per l'indirizzo di base di una struttura.
Dal puntatore incement
incremento non mi aiuta a farlo come si è in modalità a 64 bit ogni puntatore è lunga b byte.
Saluti, Dhana.
Ho postato un certo codice qui. Credo che sia giusto ..
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);
}
Soluzione
I raccomandare al posto di leggere il file dal disco usando le funzioni che si scrive come read_uint32_whatever_endian(FILE*)
e tale, e memorizzare questi in vostri nuovi struct
s in memoria a 64 bit.
Questa isola il nuovo codice dalle scelte del compilatore fa circa il layout della memoria delle vostre strutture.
Su una macchina moderna, il costo delle prestazioni di tale analisi è talmente minima che io sono sicuro che difficilmente si può misurare.
Mentre c'è un leggero angolo-caso in cui nmap
ed grandi file di database che memorizzano la stessa struttura binaria come rappresentazione in memoria del compilatore è un plus, questo caso non vale molto in pratica.
I vantaggi di una serializzazione diversa sul disco a in memoria forniscono l'abbondanza di vantaggi pratici:
- è portatile - è possibile eseguire il codice su diversi processori con diverse word-formati e diverse endians senza problemi
- è possibile estendere le strutture in qualsiasi momento - si potrebbe fare le strutture in memoria in oggetti con metodi e tali anche i metodi, virtuali C ++ e altri vantaggi di progettazione orientata agli oggetti; è possibile anche aggiungere i membri che non ottengono serializzato, come puntatori e altri campi, e si può sostenere nuove versioni dei file di database facilmente
Altri suggerimenti
Al fine di far avanzare un puntatore da qualcosa di diverso la sua dimensione originaria, si deve lanciare a char *.
Per leggere da un file che utilizza valori a 32 bit come "puntatori" che utilizzano un processore a 64 bit, è necessario ridefinire le vostre strutture in modo che i campi che prima erano i puntatori sono ancora 32 bit nel formato.
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);