在纯C语言中,我可以打开一个二进制文件,然后非常简单地将文件头直接读取到结构中。在MATLAB的C-MEX API中,这似乎是一个更繁琐的过程。我必须1:从字段名称数组初始化结构。 2:分别为每个结构字段初始化一个类型化的mxArray
。 3:将每个结构字段分别fread
放入mxArray
中。 4:分别为每个结构字段分配一个mxArray
(按数字或名称)。
是否有更简单的方法将数据直接读取到MATLAB结构中?
#pragma pack(2)
typedef struct file_header
{
int64_t preamble;
int16_t version;
int16_t mode;
int8_t software_name[32];
int32_t content;
// ...
// other fields
} file_header_t;
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
char *file_name = mxArrayToString(prhs[0]);
// read file header (C) /////////////////////////////////////////////////
file_header_t das_header;
FILE *fptr = fopen(file_name, "rb");
fread(&das_header, sizeof(file_header_t), 1, fptr);
fclose(fptr);
// read file header (MATLAB) ////////////////////////////////////////////
const int n_field = 37;
static const char *field_name[] = {
"preamble",
"version",
"mode",
"software_name",
"content"
// ...
// other field names
};
// init matlab struct
plhs[0] = mxCreateStructMatrix(1, 1, n_field, field_name);
// init mxArray containers for struct fields
mxArray *preamble = mxCreateNumericMatrix(1, 1, mxINT64_CLASS, mxREAL);
mxArray *version = mxCreateNumericMatrix(1, 1, mxINT16_CLASS, mxREAL);
mxArray *mode = mxCreateNumericMatrix(1, 1, mxINT16_CLASS, mxREAL);
mxArray *software_name = mxCreateNumericMatrix(1, 32, mxINT8_CLASS, mxREAL);
mxArray *content = mxCreateNumericMatrix(1, 1, mxINT32_CLASS, mxREAL);
// ...
// mxArray *all *subsequent *struct *fields;
fptr = fopen(file_name, "rb");
fread((int64_t*)mxGetData(preamble), 8, 1, fptr);
fread((int16_t*)mxGetData(version), 2, 1, fptr);
fread((int16_t*)mxGetData(mode), 2, 1, fptr);
fread((int8_t*)mxGetData(software_name), 1, 32, fptr);
fread((int32_t*)mxGetData(content), 4, 1, fptr);
// ...
// fread((type*)mxGetData(field_name), sizeof(type), 1, fptr);
fclose(fptr);
// assign field values
mxSetFieldByNumber(plhs[0], 0, 0, preamble);
mxSetFieldByNumber(plhs[0], 0, 1, version);
mxSetFieldByNumber(plhs[0], 0, 2, mode);
mxSetFieldByNumber(plhs[0], 0, 3, software_name);
mxSetFieldByNumber(plhs[0], 0, 4, content);
// ...
// mxSetFieldByNumber(plhs[0], 0, k, field_name);
}