利用php unpack讀取c struct的二進制數據,struct內存對齊引發的一些問題

c語言代碼php

#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讀取htm

<?php
$fd=fopen("t.log","r");
//知道C的struct 編譯器在編譯的時候會內存對齊,直接讀取12B的大小
$bin = fread($fd, 12); 
$pack = unpack("Ia/Cb/Ic",$bin); 
var_dump($pack);
fclose($fd);

  結果blog

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

多出來b2,b3,b4編譯器

  

//這裏採用字符串,而非字符
$pack = unpack("Ia/a4b/Ic",$bin);

php t.php
array(3) {
 ["a"]=> int(1234)
 ["b"]=> string(1) "a"
 ["c"]=>int(4321)
}

結果正常了
相關文章
相關標籤/搜索