我正在尝试使用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 <stdio.h>
#include <stdlib.h>
#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 <stdio.h>
#include <stdlib.h>
#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;
}
答案 0 :(得分:1)
您将“output”参数(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);
但是,请注意你有更大的问题,因为支持mxArray
的{{1}}分配并在 double *pValueInField
内销毁}。虽然您可以将指针返回到数据数组,但它将是一个悬空指针,指向已释放的数据。您需要在matread
之外分配mxArray
并将其传入,或者分配matread
并将数据复制到double *
内。否则,只要调用matread
,指针就没用了。