从 C 中读取 .mat 文件:可以读取变量;但不能 return 正确
Reading .mat file from C: Can read variable ; but cannot return PROPERLY
我正在尝试使用 MATLAB-API 来使用 C(不是 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中的矩阵; 但是,不能return正确(见最后的输出)。
(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
函数,似乎无法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);
/*
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;
}
您将 "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);
但是,请注意你有更大的问题因为支持double *pValueInField
的mxArray
在内部分配并销毁 matread
。虽然您可以 return 指向数据数组的指针,但它将是一个悬空指针,指向已释放的数据。您需要在 matread
外部分配一个 mxArray
并将其传入,或者分配一个 double *
并将数据复制到 matread
内部。否则一调用mxDestroyArray
,指针就没用了
我正在尝试使用 MATLAB-API 来使用 C(不是 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中的矩阵; 但是,不能return正确(见最后的输出)。
(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
函数,似乎无法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);
/*
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;
}
您将 "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);
但是,请注意你有更大的问题因为支持double *pValueInField
的mxArray
在内部分配并销毁 matread
。虽然您可以 return 指向数据数组的指针,但它将是一个悬空指针,指向已释放的数据。您需要在 matread
外部分配一个 mxArray
并将其传入,或者分配一个 double *
并将数据复制到 matread
内部。否则一调用mxDestroyArray
,指针就没用了