我正在处理一些我试图转换成Javascript的C源代码,我在这一行遇到了一个障碍
char ddata[512];
*(unsigned int*)(ddata+0)=123;
*(unsigned int*)(ddata+4)=add-8;
memset(ddata+8,0,add-8);我不知道这里到底发生了什么,我知道他们把字符投给了一个未签名的int,但是ddata+0和其他东西在这里做什么呢?谢谢。
发布于 2016-02-23 09:00:22
你不能说。
这是因为将char*转换到unsigned*时的行为是未定义的,除非指针从unsigned*开始,而在您的示例中则不是这样。
ddata + 0等同于ddata。
ddata + 4等价于&ddata[4],即数组的第五个元素的地址。
就其价值而言,C程序员似乎正试图将几个unsigned文本序列化为一个字节数组。但是代码是混乱的;除了我已经说过的,他们似乎是假设一个unsigned占用4个字节,这并不一定是事实。
发布于 2016-02-23 09:00:54
代码片段将记录id (123)存储为char缓冲区ddata的前4个字节中的4字节整数。然后,它将长度(add-8)存储在以下4个字节中,并最终将下面的add-8字节初始化为0。
将其转换为javascript可以以不同的方式完成,但可能不是通过构造具有相同内容的字符串来完成的。原因是字符串是javascript中的非字节缓冲区,它们包含unicode代码点,因此将字符串写入存储可能会执行一些不必要的转换。
最好的解决方案取决于实际的目标平台,在这个平台中,字节数组可以更好地匹配C代码的预期语义。
请注意,上述代码是不可移植的,并且由于各种原因而具有未定义的行为,特别是因为ddata可能没有正确地对齐以便用作通过强制转换*(unsigned int*)ddata = 123;存储unsigned int的地址,因为它假定int为4个字节,并且因为它依赖未指定的字节排序。
在Redhat上,它可能按照预期工作,相同的C代码可能在MacOS上正确执行,它使用相同的英特尔体系结构,没有多少endian排序。如何最好地将其转换为Javascript需要更多的上下文和规范。
同时,最好以这样的方式重写代码:
unsigned char ddata[512];
if (add <= 512) {
ddata[0] = 123;
ddata[1] = 0;
ddata[2] = 0;
ddata[3] = 0;
ddata[4] = ((add-8) >> 0) & 255;
ddata[5] = ((add-8) >> 8) & 255;
ddata[6] = ((add-8) >> 16) & 255;
ddata[7] = ((add-8) >> 24) & 255;
memset(ddata + 8, 0, add - 8);
}https://stackoverflow.com/questions/35572884
复制相似问题