MatlabAPI从c+;读取.mat文件+;,使用STL容器 我必须从C++中读取一些.Mat数据文件,我通过文档阅读,但是我想知道如何以干净优雅的方式处理数据,例如使用STD:vector(Maul.Mat文件大小(10M~1G),但应该认真考虑内存问题)< /P>

MatlabAPI从c+;读取.mat文件+;,使用STL容器 我必须从C++中读取一些.Mat数据文件,我通过文档阅读,但是我想知道如何以干净优雅的方式处理数据,例如使用STD:vector(Maul.Mat文件大小(10M~1G),但应该认真考虑内存问题)< /P>,c++,matlab,stdvector,mex,mat-file,C++,Matlab,Stdvector,Mex,Mat File,我的职能是: #include <stdio.h> #include "mat.h" #include <vector> int matread(const char *file, const vector<double>& pdata_v) { MATFile *pmat; pmat=matOpen("data.mat","r"); if (pmat == NULL) { printf("Error opening file %s\n"

我的职能是:

#include <stdio.h>
#include "mat.h"
#include <vector>

int matread(const char *file, const vector<double>& pdata_v) {

MATFile *pmat;

pmat=matOpen("data.mat","r");
if (pmat == NULL) {
    printf("Error opening file %s\n", file);
    return(1);
}
mxArray *pdata = matGetVariable(pmat, "LocalDouble");

// pdata -> pdata_v

mxDestroy pa1;  // clean up
return 0;
}
#包括
#包括“材料h”
#包括
int matread(常量字符*文件、常量向量和pdata_v){
MATFile*pmat;
pmat=matOpen(“data.mat”,“r”);
如果(pmat==NULL){
printf(“打开文件%s\n,文件时出错”);
申报表(1);
}
mxArray*pdata=matGetVariable(pmat,“LocalDouble”);
//pdata->pdata\u v
MXPA1;//清理
返回0;
}

因此,问题是,如何才能高效、安全地将mxArray*pdata数组复制到vector pdata_v?

您可以首先获取
mxArray*pdata
的数据指针,然后将数据复制到
vector pdata_v

double *ptr = (double *) mxGetData(pdata);
pdata_v.resize(numOfData);
memcpy(&pdata_v[0], ptr, numOfData*sizeof(double));

ps1:请特别注意,在MATLAB中,矩阵是按列顺序排列的。因此,如果
pdata
存储
[1 2 3;4 5 6]
pdata\u v
1 4 2 5 3 6


ps2:如果您想更改其内容,请将
const vector&pdata_v
更改为
vector&pdata_v

这里有另一个想法。如果你对C++代码中的裸指针过敏(顺便说一下,没有错误),你可以用一个删除器将裸指针包装在一个Boost或C++ 11智能指针中,当指针超出范围时,调用一个DELTER调用正确的<代码> MXDebug YARAY()/<代码>。这样,您就不需要副本,您的用户代码也不需要知道如何正确地解除分配

typedef共享\u ptr mxSmartPtr;
mxSmartPtr readMATarray(MATFile*pmat,const char*varname)
{
mxSmartPtr pdata(matGetVariable(pmat,varname),
mxDestroyArray);//设置删除器
返回pdata;
}
int some_函数(){
mxSmartPtr pdata=readMATarray(pmat,“LocalDouble”);
...
//pdata超出范围,mxDestroy会自动调用
}

想法如下:

以下是使用的示例:

测试材料cpp
#包括“mat.h”
#包括
#包括
void matread(const char*文件,std::vector&v)
{
//打开MAT文件
MATFile*pmat=matOpen(文件“r”);
如果(pmat==NULL)返回;
//提取指定的变量
mxArray*arr=matGetVariable(pmat,“LocalDouble”);
如果(arr!=NULL&&mxisDuble(arr)&&!mxIsEmpty(arr)){
//复制数据
mwSize num=mxGetNumberOfElements(arr);
双*pr=mxGetPr(arr);
如果(pr!=NULL){
v、 reserve(num);//快于resize:-)
v、 分配(pr,pr+num);
}
}
//清理
MX阵列(arr);
matClose(pmat);
}
int main()
{
std::向量v;
matread(“data.mat”,v);
对于(size\u t i=0;i>LocalDouble=magic(4)
本地双精度=
16     2     3    13
5    11    10     8
9     7     6    12
4    14    15     1
>>save data.mat LocalDouble
现在我们运行程序:

C:\>test\u mat.exe
16
5.
9
4.
2.
11
7.
14
3.
10
6.
15
13
8.
12
1.

文件很大?内存可能是一个问题?我们讨论的文件大小是多少?
fgets
然后自己跟踪文件指针似乎是一个可行的方法。是的,这很难,但并不强调内存和它的速度。从MATLAB中使用
fwrite
并将数据放在一个简单的二进制文件中更容易RMAT,C++可以简单地读取(甚至内存映射)。谢谢PS1和2!我可以问,代替MeMcPy(在我看来更像C,它是不是容易出错?),像PdAtAyv(PTR,PTR+NUMILIONE元素)使用安全吗?@洛尼珀,如果你正确使用它,它比你提到的C++风格更容易出错。您的解决方案成功编译,但给出了“分段错误11”,我提到的方法在编译时给出了错误:“调用(std::vector)(double*&,double*)”之前,请确保为
vector pdata\u v
分配内存,例如
pdata\u v.resize(numOfData)
@lorniper:如果你想使用这种语法,你可以调用:
pdata\u v.assign(ptr,ptr+num);
where
double*ptr=mxGetPr(pdata);
size\u t num=mxGetNumberOfElements(pdata)
正是我所期望的!只有一点,为什么matGetVariable而不是matGetNextVariable?如果从mat文件中读取多个向量,哪一个更好?@lorniper:我想保持示例的简单性。基本上,当您想按名称检索特定变量时,您可以使用
matGetVariable
。如果您想在所有变量上进行迭代l将变量保存在MAT文件中,在循环中使用
matGetNextVariable
。查看MATLAB附带的
matdgns.c
示例(查看
$MATLABROOT/extern/examples/eng_-MAT/
文件夹)对于导入/导出功能非常有用。很好!@Amro是否只能在Matlab本身中使用mat.h?我们不能在其他IDE中使用它吗?@Sndn当然可以。
mex-client engine
was,您可以通过指定所需的参数来自行构建应用程序。注意
mex-v..
显示了实际的编译器调用。C的出色使用++11
共享\u ptr
以简化使用。我正在记下这一点!