从C读取.mat文件:可以读取变量; 但不能正确返回

我正在尝试使用MATLAB-API使用C(NOT C ++)读取.mat文件。

这是MATLAB代码,它会创建我想要的.mat文件:

A = [[1 2 3]; [5 7 1]; [3 5 9]]; B = [[2 4];[5 7]]; Creator = 'DKumar'; nFilters = 2; Filters{1} = [[-1.0 -1.0 -1.0]; [-1.0 8 -1.0]; [-1.0 -1.0 -1.0]]; Filters{2} = 2.0*[[-1.0 -1.0 -1.0]; [-1.0 8 -1.0]; [-1.0 -1.0 -1.0]]; cd('/home/dkumar/CPP_ExampleCodes_DKU/Read_mat_File'); save('Test_FILE.mat', 'A', 'B', 'Creator', 'nFilters', 'Filters'); 

请注意,我还需要阅读细胞结构或类似的东西。

(1)在C代码中,似乎我可以读取存储在.mat中的矩阵就好了; 但是,无法正常返回 (最后看输出)。

(2)我仍然不知道在这个例子中存储可能在大小上变化的双矩阵的单元结构

下面是完整的C代码。 首先,函数matread ,它可以看似正确地读取数据。

 #include  #include  #include "/usr/local/MATLAB/R2011b/extern/include/mat.h" struct stDoubleMat{ double* pValueInField; int nRows, nCols; }; void matread(const char *file, const char *FieldName2Read, struct stDoubleMat oDoubleMat_LOC) { printf("Reading file %s...\n\n", file); //Open file to get directory MATFile* pmat = matOpen(file, "r"); if (pmat == NULL) { printf("Error opening file %s\n", file); return; } // extract the specified variable mxArray *arr = matGetVariable(pmat, FieldName2Read); double *pr; if (arr != NULL && !mxIsEmpty(arr)) { // copy data mwSize num = mxGetNumberOfElements(arr); pr = mxGetPr(arr); if (pr != NULL) { oDoubleMat_LOC.pValueInField = pr; oDoubleMat_LOC.nRows = mxGetM(arr); oDoubleMat_LOC.nCols = mxGetN(arr); } printf("From inside the function \n") ; printf( "oDoubleMat_LOC.nRows %i ; oDoubleMat_LOC.nCols %i \n", oDoubleMat_LOC.nRows , oDoubleMat_LOC.nCols); }else{ printf("nothing to read \n") ; } // cleanup mxDestroyArray(arr); matClose(pmat); return; } 

在同一个文件中, main函数似乎无法返回读取数据:

 int main(int argc, char **argv) { const char *FileName = "/home/dkumar/CPP_ExampleCodes_DKU/Read_mat_File/Test_FILE.mat"; const char *FieldName2Read = "A"; struct stDoubleMat oDoubleMat; matread(FileName, FieldName2Read, oDoubleMat); double* v = oDoubleMat.pValueInField; printf("From main \n"); printf( "oDoubleMat.nRows %i ; oDoubleMat.nCols %i \n", oDoubleMat.nRows , oDoubleMat.nCols); /* for (int i = 0; i < oDoubleMat.nElements; i++) { std::cout <<" copied value : " << *v << "\n"; v = v +1; }*/ return 0; } 

这是输出

 $ gcc -o Test Read_MatFile_DKU_2.c -I/usr/local/MATLAB/R2011b/extern/include -L/usr/local/MATLAB/R2011b/bin/glnxa64 -lmat -lmx $ ./Test Reading file /home/dkumar/CPP_ExampleCodes_DKU/Read_mat_File/Test_FILE.mat... From inside the function oDoubleMat_LOC.nRows 3 ; oDoubleMat_LOC.nCols 3 From main oDoubleMat.nRows 0 ; oDoubleMat.nCols 0 

更新:

这是更新的代码,它读取矩阵字段就好了。 我仍然no clue about how to read "cell-structure"

 #include  #include  #include "/usr/local/MATLAB/R2011b/extern/include/mat.h" mxArray *arr; struct stDoubleMat{ double* pValueInField; int nRows, nCols; }; void matread(const char *file, const char *FieldName2Read, struct stDoubleMat* poDoubleMat_LOC) { printf("Reading file %s...\n\n", file); //Open file to get directory MATFile* pmat = matOpen(file, "r"); if (pmat == NULL) { printf("Error opening file %s\n", file); return; } // extract the specified variable arr = matGetVariable(pmat, FieldName2Read); double *pr; if (arr != NULL && !mxIsEmpty(arr)) { // copy data mwSize num = mxGetNumberOfElements(arr); pr = mxGetPr(arr); if (pr != NULL) { poDoubleMat_LOC->pValueInField = pr; poDoubleMat_LOC->nRows = mxGetM(arr); poDoubleMat_LOC->nCols = mxGetN(arr); } printf("From inside the function \n") ; printf( "oDoubleMat_LOC.nRows %i ; oDoubleMat_LOC.nCols %i \n", poDoubleMat_LOC->nRows , poDoubleMat_LOC->nCols); }else{ printf("nothing to read \n") ; } // close the file matClose(pmat); return; } int main(int argc, char **argv) { const char *FileName = "/home/dkumar/CPP_ExampleCodes_DKU/Read_mat_File/Test_FILE.mat"; const char *FieldName2Read = "A"; struct stDoubleMat oDoubleMat; matread(FileName, FieldName2Read, &oDoubleMat); double* v = oDoubleMat.pValueInField; printf("From main \n"); printf( "oDoubleMat.nRows %i ; oDoubleMat.nCols %i \n", oDoubleMat.nRows , oDoubleMat.nCols); int i; for (i = 0; i < oDoubleMat.nCols*oDoubleMat.nRows; i++) { printf(" copied value : %f \n", *v); v = v +1; } // cleanup the mex-array mxDestroyArray(arr); return 0; } 

您通过值将“输出”参数( oDoubleMat_LOC )传递给matread ,因此您实际上永远无法获得输出,因为它是在输入上复制的(即仅在本地修改):

 void matread(const char *file, const char *FieldName2Read, struct stDoubleMat oDoubleMat_LOC) /* oDoubleMat_LOC copied */ 

由于您使用的是C,其中引用不可用,因此传递指针。 重新定义matread

 void matread(const char *file, const char *FieldName2Read, struct stDoubleMat *oDoubleMat_LOC) /* use a pointer */ 

然后在matread ,你需要取消引用它来修改它的字段(用->而不是. ):

 oDoubleMat_LOC->pValueInField = pr; oDoubleMat_LOC->nRows = mxGetM(arr); oDoubleMat_LOC->nCols = mxGetN(arr); 

main ,这样称呼:

 struct stDoubleMat oDoubleMat; matread(FileName, FieldName2Read, &oDoubleMat); 

但是,请注意,由于支持double *pValueInField matread分配和销毁 ,因此存在更大的问题 。 虽然您可以返回指向数据数组的指针,但它将是一个悬空指针,指向解除分配的数据。 您需要在matread之外分配matread并将其传入,或者分配double *并在matread数据复制到其中。 否则,只要调用mxDestroyArray ,指针就没用了。