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);

}
È stato utile?

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 structs 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 nmaped 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);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top