利用php unpack读取c struct的二进制数据,struct内存对齐引起的一些问题
c语言代码
#include <stdio.h> struct test{
int a;
unsigned char b;
int c;
};
int main(){
FILE *fp;
fp = fopen("t.log", "w+");
struct test t={1234, 'a', 4321};
struct test t1; fwrite(&t, sizeof(struct test), 1, fp);
rewind(fp);
fread(&t1, sizeof(struct test), 1, fp);
printf("%d\n%c\n%d\n", t1.a, t1.b, t1.c); fclose(fp);
return 0;
}
C的struct 编译器在编译的时候会内存对齐,看到的是12字节,而不是9字节
ls -l //可以看到大小12
-rwxrwxrwx 1 root root 12 4月 12 00:07 t.log od t.log //以八进制查看文件
0000000 002322 000000 000141 000000 010341 000000
0000014
php读取
<?php
$fd=fopen("t.log","r");
//知道C的struct 编译器在编译的时候会内存对齐,直接读取12B的大小
$bin = fread($fd, 12);
$pack = unpack("Ia/Cb/Ic",$bin);
var_dump($pack);
fclose($fd);
结果
php t.php
array(3) {
["a"]=>
int(1234)
["b"]=>
int(97)
["c"]=>
int(-520093696)
}
c 的结果-52009369显示不对
经过一顿调试发现,还是没有完全理解 内存对齐
按照内存对齐规则 unsigned char b;会有4个字节的空间,第一个存储数据,其余三个空闲
struct test{
int a; [1-4]
unsigned char b; [5-8]//这里是4个而非一个,空闲三个
int c;[9-12]
};
<?php
//注意这里改成C4
$pack = unpack("Ia/C4b/Ic",$bin); php t.php
array(6) {
["a"]=> int(1234)
["b1"]=> int(97)
["b2"]=> int(0)
["b3"]=> int(0)
["b4"]=> int(0)
["c"]=> int(4321)
}
多出来b2,b3,b4
//这里采用字符串,而非字符
$pack = unpack("Ia/a4b/Ic",$bin); php t.php
array(3) {
["a"]=> int(1234)
["b"]=> string(1) "a"
["c"]=>int(4321)
} 结果正常了
利用php unpack读取c struct的二进制数据,struct内存对齐引起的一些问题的更多相关文章
- SQLite数据库如何存储和读取二进制数据
SQLite数据库如何存储和读取二进制数据 1. 存储二进制数据 SQLite提供的绑定二进制参数接口函数为: int sqlite3_bind_blob(sqlite3_stmt*, int, co ...
- 前端H5中JS用FileReader对象读取blob对象二进制数据,文件传输
HTML5中的Blob对象只是二进制数据的容器,本身并不能操作二进制,故本篇将对其操作对象FileReader进行介绍. FileReader FileReader主要用于将文件内容读入内存,通过一系 ...
- HTML5新特性之文件和二进制数据的操作
历史上,JavaScript无法处理二进制数据.如果一定要处理的话,只能使用charCodeAt()方法,一个个字节地从文字编码转成二进制数据,还有一种办法是将二进制数据转成Base64编码,再进行处 ...
- python numpy实现多次循环读取文件 等间隔过滤数据
numpy的np.fromfile会出现如下的问题,只能一次性读取文件的内容,不能追加读取,连续两次的np.fromfile读到的东西一样 如果数据文件太大(几个G或以上)不能一次性全读进去,需要追加 ...
- erlang二进制数据垃圾回收机制
erlang二进制数据在内存中有两种存在形式,当数据大小不到 64 bytes,就直接存在进程堆内.假设超过了64 bytes.就被保存到进程外的共享堆里,能够给节点内全部进程共享. erlang有两 ...
- Python使用struct处理二进制(pack和unpack用法)
转载自:http://www.cnblogs.com/gala/archive/2011/09/22/2184801.html 这篇文章写的很好,所以无耻的转了.. 有的时候需要用python处理二进 ...
- Pytho, struct处理二进制(pack和unpack)
[转]Python使用struct处理二进制(pack和unpack用法) Leave a reply 转载自:http://www.cnblogs.com/gala/archive/2011/09/ ...
- 使用struct处理二进制
有的时候需要用python处理二进制数据,比如,存取文件.socket操作时.这时候,可以使用python的struct模块来完成. struct模块中最重要的三个函数是pack(), unpack( ...
- Python使用struct处理二进制
有的时候需要用python处理二进制数据,比如,存取文件,socket操作时.这时候,可以使用python的struct模块来完成.可以用 struct来处理c语言中的结构体. struct模块中最重 ...
随机推荐
- HDU_1042——阶乘,万进制
#include <cstdio> ; const int BASE = MAX; int main() { int n, i, j; while(~scanf("%d" ...
- Node开发入门
介绍 Node.js采用google的V8虚拟机来解释和执行javascript,也就是允许脱离浏览器环境运行javascript代码. Hello World 婴儿说的第一个字一般是"妈& ...
- 《SDN核心技术剖析和实战指南》2.2OpenFlow交换机规范小结
这节的内容相当多,主要是介绍OpenFlow标准特别是流表的相关特性. 典型的OpenFlow标准由三部分组成:安全通道,流表和OpenFlow协议.注意这个标准是一份设备标准,并不单指OpenFlo ...
- You should rebuild using libgmp >= 5 to avoid timing attack vulnerability.", PowmInsecureWarning
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAApcAAAB3CAIAAADZ1fxtAAAbFElEQVR4nO2dzbHDOo6FHY9S0WqqZt
- Java ConcurrentHashmap 解析
总体描述: concurrentHashmap是为了高并发而实现,内部采用分离锁的设计,有效地避开了热点访问.而对于每个分段,ConcurrentHashmap采用final和内存可见修饰符Volat ...
- 双外边距浮动bug;3像素文本偏移bug;IE6以下相对定位中的绝对定位bug
http://www.cnblogs.com/star91/p/5458100.html
- 关于CCRect
一直有一个误区,因为之前处理的公司引擎是屏幕坐标系 导致觉得CCRect的坐标起始值(x,y),习惯性的认为就是左上角的点. 但是,真正的x,y值,是跟x轴与y轴相对应的.
- Solr的安装
1. JDK要求 Solr 4.10 要求JDK版本必须是1.7或更高. 下载地址: http://www.apache.org/dyn/closer.cgi/lucene/solr/ 下载得到z ...
- java基础之导入(药师点评)
/** * 药师点评的导入 * @param request * @param response * @param f * @param tmallTcMessageImport * @return ...
- 《javascript设计模式》--接口
关于javascript设计模式书中的接口,记录如下 //TODO 增加了一个判断条件,可以只在生产环境中调用 接口var Interface = function(name,methods){ i ...