Как добавить n байтов в 64 -битную систему
-
20-09-2019 - |
Вопрос
Я работаю в 64 -битной 64 -битной системе OSX 64 -битной.
Я читаю файл базы данных Legacy. Он загружается в блок памяти и использует смещения, которые читают в структуры. Это написано в 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
с
Это изолирует ваш новый код от выбора, который компилятор делает о макете памяти ваших структур.
На современной машине стоимость такого анализа производительности настолько минимальна, что я уверен, что вы вряд ли сможете ее измерить.
Пока есть легкий угловой случай, где nmap
Эд крупных файлов базы данных, которые хранят ту же двоичную структуру, что и представление компилятора в памяти, является плюсом, этот случай не стоит на практике.
Преимущества другой сериализации на диске в памяти обеспечивают много практических плюсов:
- Это портативно - вы можете запустить свой код на разных процессорах с разными размерами слов и разными энданами без проблем
- Вы можете расширить структуры в любое время - вы можете превратить структуры в памяти в объекты с помощью методов и тому подобным, даже виртуальным методам 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);