【发布时间】:2020-01-03 05:24:09
【问题描述】:
我正在尝试序列化 PHP 操作码。我对代码感到困惑。请检查以下代码。代码是什么意思。
(ptr) = (void*)((char*)(ptr) - (char*)script->mem)
如何序列化op_array?
【问题讨论】:
-
发布您的代码,而不是指向它的链接。链接烂了。
-
看起来它正在将指针变成偏移量。
我正在尝试序列化 PHP 操作码。我对代码感到困惑。请检查以下代码。代码是什么意思。
(ptr) = (void*)((char*)(ptr) - (char*)script->mem)
如何序列化op_array?
【问题讨论】:
所以,这是一个古老的游戏编码器技巧,旨在序列化/反序列化指向/来自磁盘的指针。
这有点脏,但让我看看能不能解释一下。使用一个非常简单的例子,让我们想象一下我有这个结构:
struct FileContents
{
char text[10] = {0,1,2,3,4,5,6,7,8,9};
char* ptr = text + 5; //< point to element 5
};
我想一次性使用 fread/fwrite 读/写该结构。如果我只是这样做:
void writeFile(FileContents contents)
{
FILE* fp = fopen("blah.dat", "wb");
fwrite(&contents, sizeof(FileContents), 1, fp);
fclose(fp);
}
这对于存储在 contents.text 中的值可以正常工作,但对于 contents.ptr 会非常失败(因为这个指针指向一个内存地址,我们不太可能重新声明它如果我们想再次读取数据,则使用相同的内存位置)。
因此,我们需要对所有指针值进行 unfix/refix 操作。我们可以这样做:
struct FileContents
{
char text[10] = {0,1,2,3,4,5,6,7,8,9};
void* ptr = (text + 5); //< point to element 5
// convert 'ptr' to be an integer offset from the start of the struct
void unfix()
{
// heres the first byte we will write to the file
char* startOfFile = (char*)this;
// here's the problematic pointer value.
char* ptrValue = ptr;
// now lets compute a byte offset from the start of the struct,
// to the memory location ptr is pointing to...
// (in this case, the offset will be 5)
size_t offset = ptrValue - startOfFile;
// now lets modify the value of ptr so that it now stores a byte
// offset, rather than a memory location. (We need to cast the
// offset to a pointer value, otherwise this wont work)
ptr = (void*)offset;
}
// AFTER reading the file (deserialise), we need to convert
// that integer offset back into a valid memory address...
void refix()
{
// grab start of struct in memory
char* startOfFile = (char*)this;
// and add the offset to the start of the file, to
// get the valid memory location
ptr = startOfFile + ((size_t)ptr);
}
};
【讨论】:
您似乎有void* ptr 和sometype* script->mem,将它们都转换为char* 并从另一个中减去,然后将结果转换为void*
【讨论】: