从C读取.mat文件:可以读取变量;但无法正确返回 [英] Reading .mat file from C: Can read variable ; but cannot return PROPERLY
问题描述
我正在尝试使用MATLAB-API来使用C(不是C ++)读取.mat文件.
I am trying to use MATLAB-API to read .mat file using C (NOT C++).
这是MATLAB代码,可以创建我想要的.mat文件:
This is MATLAB code which would create sort of .mat file I want:
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');
请注意,我还需要阅读单元结构或类似内容.
Please notice that I also need to read cell-structure or something similar.
(1)在C代码中,看来我可以很好地读取存储在.mat中的矩阵; 但是无法正确返回(请参阅最后的输出).
(1) In the C code, it seems that I can read matrix stored in .mat just fine; but, cannot return properly (see the output in the end).
(2)我仍然不知道单元格结构,在此示例中,该单元将存储大小可能不同的双矩阵.
(2) I still have no idea about cell-structure which in this example would STORE DOUBLE MATRICES which may vary in size.
完整的C代码如下.首先,函数matread
看起来可以正确读取数据.
Full-C code follows. First, the function matread
, which can seemingly read the data properly.
#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
函数似乎无法返回读取的数据:
In the same file, the main
function, which seems to be unable to return the read data:
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"
.
Here is the updated code which read matrix-field just fine. I still have 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;
}
推荐答案
您将输出"自变量(oDoubleMat_LOC
)按值传递给matread
,因此,由于将其复制到输入中,因此您将永远无法获得输出(即仅在本地修改):
You pass the "output" argument (oDoubleMat_LOC
) by value to matread
, so you can never actually get an output because it is copied on input (i.e. only modified locally):
void matread(const char *file, const char *FieldName2Read,
struct stDoubleMat oDoubleMat_LOC) /* oDoubleMat_LOC copied */
由于您使用的是C(无法使用引用),因此请传递一个指针.重新定义matread
:
Since you are using C, where references are not available, pass a pointer. Redefine matread
:
void matread(const char *file, const char *FieldName2Read,
struct stDoubleMat *oDoubleMat_LOC) /* use a pointer */
然后在matread
内部,您需要取消引用它以修改其字段(使用->
而不是.
):
Then inside matread
, you need to dereference it to modify its fields (with ->
instead of .
):
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
.虽然您可以将指针返回到数据数组,但它将是一个悬空指针,该指针指向已释放的数据.您需要在matread
之外分配一个mxArray
并传递给它,或者在matread
内分配一个double *
并将数据复制到其中.否则,一旦调用mxDestroyArray
,该指针就无用了.
However, note that you have bigger problems because the mxArray
that is backing double *pValueInField
is both allocate and destroyed inside matread
. While you can return the pointer to the data array, it will be a dangling pointer, which points to deallocated data. You'll need to either allocate an mxArray
outside of matread
and pass it in, or allocate a double *
and copy the data into it inside matread
. Otherwise, as soon as mxDestroyArray
is called, the pointer is useless.
这篇关于从C读取.mat文件:可以读取变量;但无法正确返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!