Как добавить n байтов в 64-битной системе - PullRequest
1 голос
/ 12 февраля 2010

Я работаю в 64-битной x_86 64-битной системе OSX.

Я читаю файл устаревшей базы данных.Он загружается в блок памяти и, используя смещения, считывается в структуры.Он написан в 32-битном режиме.

Таким образом, для правильного чтения в 64-битном режиме я хочу добавить n байтов к базовому адресу структуры.

С момента появления указателя

Приращение не помогает мне сделать это. Так как в 64-битном режиме каждый указатель имеет длину в байт.

С уважением, Дхана.

Я разместил здесь некоторый кодЯ думаю, это правильно ..

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

}

Ответы [ 2 ]

1 голос
/ 12 февраля 2010

Чтобы продвинуть указатель на что-то отличное от его собственного размера, вы должны привести к 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);
1 голос
/ 12 февраля 2010

I рекомендует вместо этого прочитать файл с диска с помощью написанных вами функций, таких как read_uint32_whatever_endian(FILE*) и т. Д., И сохранить их в новой 64-битной памяти struct s.

Это изолирует ваш новый код от выбора, который компилятор делает для структуры памяти ваших структур.

На современном компьютере производительность такого анализа настолько минимальна, что, я уверен, вы вряд ли сможете его измерить.

Хотя есть угловой случай незначительный , в котором nmap большие файлы базы данных, которые хранят ту же двоичную структуру, что и представление компилятора в памяти, являются плюсом, на практике этот случай не стоит много .

Преимущества различной сериализации на диске и в памяти обеспечивают множество практических плюсов:

  • это переносимо - вы можете без проблем запускать свой код на разных процессорах с разными размерами слов и различными порядковыми номерами
  • вы можете расширять структуры в любое время - вы можете превратить структуры в памяти в объекты с помощью методов и тому подобного, даже виртуальных методов C ++, и других преимуществ объектно-ориентированного проектирования; вы также можете добавлять члены, которые не сериализуются, например указатели и другие поля, и вы можете легко поддерживать новые версии файлов базы данных
...