在C中,“operation”的意思是什么?

huangapple go评论79阅读模式
英文:

What is the meaning of operation in c

问题

我正在尝试序列化PHP的操作码。我对这段代码感到困惑。请检查以下代码。这段代码的含义是什么。

(ptr) = (void*)((char*)(ptr) - (char*)script->mem)

如何序列化op_array

英文:

I am trying to serialize PHP opcode. I am confused with code. Please check following code. What is the meaning of the code.

(ptr) = (void*)((char*)(ptr) - (char*)script->mem)

https://github.com/php/php-src/blob/6aaab9adf7619c121c19701022aeb8d88f9c3bab/ext/opcache/zend_file_cache.c#L112

How to serialize op_array ?

答案1

得分: 7

这是一个老的游戏编程技巧,用于将指针序列化/反序列化到磁盘。

有点不太规范,但让我尽量解释一下。以一个极为简化的示例为例,假设我有以下结构体:

struct FileContents
{
  char text[10] = {0,1,2,3,4,5,6,7,8,9};
  char* ptr = text + 5; //< 指向第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会出现严重问题(因为此指针引用内存地址,如果我们想再次读取数据,很难重新获取相同的内存位置)。

因此,我们需要对所有指针值进行修复/还原操作。我们可以通过以下方式实现:

struct FileContents
{
  char text[10] = {0,1,2,3,4,5,6,7,8,9};
  void* ptr = (text + 5); //< 指向第5个元素

  // 将 'ptr' 转换为相对于结构体开头的整数偏移量
  void unfix()
  {
    // 这是我们将要写入文件的第一个字节
    char* startOfFile = (char*)this;

    // 这是有问题的指针值。
    char* ptrValue = ptr;

    // 现在,让我们计算从结构体开头到指针指向的内存位置的字节偏移量...
    // (在这种情况下,偏移量将为5)
    size_t offset = ptrValue - startOfFile;

    // 现在,让我们修改ptr的值,使其现在存储一个字节偏移量,而不是内存位置。
    // (我们需要将偏移量强制转换为指针值,否则这不会起作用)
    ptr = (void*)offset;
  }

  // 读取文件后(反序列化),我们需要将该整数偏移量重新转换为有效的内存地址...
  void refix()
  {
    // 获取内存中结构体的起始位置
    char* startOfFile = (char*)this;

    // 并将偏移量添加到文件的起始位置,以获取有效的内存位置
    ptr = startOfFile + ((size_t)ptr);
  }
};
英文:

So, this is an old game coders trick, intended to serialise/deserialise a pointer to/from disk.

It's a little dirty, but lets see if I can explain somehow. Using a vastly oversimplified example, lets imagine I have this struct:

struct FileContents
{
  char text[10] = {0,1,2,3,4,5,6,7,8,9};
  char* ptr = text + 5; //< point to element 5
};

and I want to read/write that struct using fread/fwrite in one go. If i was to simply do:

void writeFile(FileContents contents)
{
  FILE* fp = fopen("blah.dat", "wb");
  fwrite(&contents, sizeof(FileContents), 1, fp);
  fclose(fp);
}

This would work fine for the values stored in contents.text, but would horribly fail for contents.ptr (since this pointer is referring to a memory address, and it's unlikely we will be able to re-claim that same memory location if we wanted to read the data again).

As such, we need an unfix/refix operation on all the pointer values. We can achieve this by doing:

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

答案2

得分: 2

似乎您有一个 void* ptrsometype* script->mem,您将它们都转换为 char* 并相互减去,然后将结果转换为 void*

英文:

it seems that you have a void* ptr and sometype* script->mem, you cast them both to char* and subtract one from another, then you cast the result to void*

huangapple
  • 本文由 发表于 2020年1月3日 13:24:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/59573573.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定