MATLAB C MEX API: прямо в struct? - PullRequest
1 голос
/ 24 мая 2019

В чистом 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);  
}  

...