1. 程式人生 > 其它 >用python做科學計算(一)C語言讀取python生成的二進位制檔案

用python做科學計算(一)C語言讀取python生成的二進位制檔案

在C語言中我們可以通過struct關鍵字定義結構型別,結構中的欄位佔據連續的記憶體空間,每個結構體
佔用的記憶體大小都相同,因此可以很容易地定義結構陣列。和C語言一樣,在NumPy中也很容易對這
種結構陣列進行操作。只要NumPy中的結構定義和C語言中的定義相同,NumPy就可以很方便地讀取
C語言的結構陣列的二進位制資料,轉換為NumPy的結構陣列。

Python的結構陣列

import numpy as np
persontype = np.dtype({
'names':['name', 'age', 'weight'],
'formats':['S32','i', 'f']})
a = np.array([("Zhang",32,75.5),("Wang",24,65.2)],
dtype=persontype)

通過呼叫a.tostring或者a.tofile方法,可以直接輸出陣列a的二進位制形式:

a.tofile("test.bin")

C語言的結構體為了記憶體定址方便,會自動的新增一些填充用的位元組,這叫做記憶體對齊。例如
如果把下面的name[32]改為name[30]的話,由於記憶體對齊問題,在name和age中間會填補兩
個位元組,最終的結構體大小不會改變。因此如果numpy中的所配置的記憶體大小不符合C語言的
對齊規範的話,將會出現資料錯位。為了解決這個問題,在建立dtype物件時,可以傳遞引數
align=True,這樣numpy的結構陣列的記憶體對齊和C語言的結構體就一致了。

C語言讀取

int main(int argc, char *argv[])
{
   /* FILE *fp=NULL;
    int i;
    fp=fopen("D:\\Code\\QtWorkPlace\\day02\\calculator\\test.bin","rb");
    fread(p,sizeof (struct person),2,fp);
    fclose(fp);
    for(i=0;i<2;i++)
    {
        printf("%s  %d  %f\n",p[i].name,p[i].age,p[i].weight);
    }
    getchar();*/



    /*QByteArray aa;
    QFile file("D:\\Code\\QtWorkPlace\\day02\\calculator\\test.bin");
    file.open(QIODevice::ReadOnly);
    char *bf;
    aa=file.readAll();
    bf=aa.data();
    file.close();
    filesize=aa.length();

    for(int i=0;i<2;i++)
    {
        p[i]=*(reinterpret_cast<person_st *>(aa.data()+i*sizeof (person_st)));
        printf("%s  %d  %f\n",p[i].name,p[i].age,p[i].weight);
    }*/

    QFile file("D:\\Code\\QtWorkPlace\\day02\\calculator\\test.bin");
    file.open(QIODevice::ReadOnly);
    QDataStream in(&file);
    char s[2048];
    int len;
    in.readRawData(s,2*sizeof (person_st));

    for(int i=0;i<2;i++)
    {
        p[i]=*(reinterpret_cast<person_st *>(s+i*sizeof (person_st)));
        printf("%s  %d  %f\n",p[i].name,p[i].age,p[i].weight);
    }
}

這三種方法都可以,注意寫對檔案路徑!

Qt中的QByteArray和自定義結構體之間的相互轉換

  1. QByteArray轉換為自定義結構體

custom_struct *struct_data = reinterpret_cast<custom_struct *>(array_data.data());
2. 自定義結構體轉換為QByteArray

QByteArray array_data;
array_data.append((char*)&struct_data, sizeof(struct_data));

參考

Qt中的QByteArray和自定義結構體之間的相互轉換