matlab与C++数据交换

  • Post author:
  • Post category:其他




一组MATLAB和 C++数据交换类的设计



南京航空航天大学 san

email :



visualsan@yahoo.cn

(源代码:

http://blog.csdn.net/visualsan/archive/2011/03/05/6226205.aspx

)


一组MATLAB和 <wbr>C++数据交换类的设计

总体结构图

本文将针对如何进行 MATLAB 和 C++ 交互进行探讨,编程环境问为 matlab2009 和 VC6.0 。具体如何设置编程环境请参考 help 。内容总体分三部分: 1.matlab 引擎调用类封装。 2. 数据接口类设计,包括 mat 类型文件操作类设计。 3. 具体举几个实例。所有源代码包括例子,在我的空间中可以找到,有参考需要的朋友可以关注一下。

MATLAB 引擎总体结构分成两部分:数据交换和后台计算服务,由 matlab 命令控制。数据交换接口负责数据输入和数据输出。数据输入将计算说需要的变量导入到计算引擎中;数据输出接口则将计算结果提取出来进一步处理,典型的matlab应用是首先向matlab 传递参数、然后进行复杂的运算,最后提取感兴趣的结果。利用matlab 强大的计算能力以及C++的灵活性可发挥各种功能的极限,从而提高工作效率。关于matlab 和c++的相互调用的文章很多,但是在两者之间进行数据传递是一个比较麻烦的事情,要求程序员对MATLAB 的C API相当熟悉,所以非常不便。我接触MATLAB 和C++有几年了,相关书籍和文件教程让我受益匪浅,闲暇之余就总结了一下自己所学的知识,用面向对象方法开发了matlab和c++交互的类,写出来探讨一下。

计算引擎分为全局引擎和局部引擎。全局引擎只有一个,一旦启动全局引擎,则所有的计算结果和变量都是全局共享的。局部引擎是独立于线程的一个计算引擎,它的数据是局部拥有的,可以启动任意多的局部引擎,取决于计算机配置。启动一个局部引擎相当于开启一个独立的 MATLAB 线程,由于启动 MATLAB 是一个很耗时间的过程,因此应该尽量减少局部引擎的启动数量。引擎控制有类 CMatlabEngine 控制。 CMatlabEngine 的结构如下:



一组MATLAB和 <wbr>C++数据交换类的设计

bSingleUse=1 表示启动局部引擎, bSingleUse=0 表示启动全局引擎,全局引擎在第一次调用时打开 MATLAB ,以后每调用一次 OpenEngine 打开全局 MATLAB ,则引用计数加一;调用一次 closeEngine 引用计数减一。当引用计数为 0 时,表示当前没有程序对全局 MATLAB 进行调用,此时将自动关闭 MATLAB 。

调用 void SetEngineVisible(BOOL bVisible) 将决定是否显示 MATLAB 的窗口界面。函数 void PutVar(char *name,MatlabData* d) 将向 MATLAB 空间中添加一个自定义变量,其中 name 为变量名称, d 为变量内容,若该变量已经存在,则调用该函数将覆盖已存在变量值。函数 BOOL GetVar(char *name,MatlabData** d) 将从 MATLAB 空间中提取一个变量,其中 name 为变量名称, d 为输出指向内容指针的指针,若该变量不存在,则返回 FALSE 。

void EvalString(char* matlabString) 可以和计算引擎进行命令交互, matlabString 为命令,和常规使用 MATLAB 软件所进行的输入一致。一旦调用某个命令, MATLAB 将有反馈输出,可能是计算结果,也可能是错误信息,这些信息可以通过调用 const char* GetOutPut() 来获取。

2. 数据类型接口设计



所有 MATLAB的 C API的数据类型是 mxArray , MATLAB 提供了一组 C

API 来进行数据操作。 mxArray 是一种包含多种类型的数据,可以是数值,字符, cell 或者是结构体;数据类型可以是标量,矩阵,STRUCT或者是 Array 。


一组MATLAB和 <wbr>C++数据交换类的设计

针对实际应用,将常用的数据类型进行接口设计。数据结构可分为标量,矩阵和阵列。数据类型有双精度浮点数,单精度浮点数, 32 位整数, 64 位整数,字符串,布尔型。

如图所示,将数据结构分为三种,分别是:标量、矩阵和阵列。将数据类型分位四种:

浮点数、布尔型,整形和字符串。类继承关系图如下



一组MATLAB和 <wbr>C++数据交换类的设计


以 ImxAray 为借口类,派生出矩阵 xMatrix<T> 和阵列 xAray<T> ,其中 T 位具体类型,采用模板技术,再将类型 T 具体化位实际数据类型如 int,double 等,可以得到相应的矩阵类和阵列类如 xMatrixDouble , xMatrixInt 等。


一组MATLAB和 <wbr>C++数据交换类的设计

图中并为列出所有模板绑定的类型,更具体的类列表如下:



// 矩阵






typedef xMatrix<bool> xMatrixBool;








typedef xMatrix<char> xMatrixChar;








typedef xMatrix<double> xMatrixDouble;








typedef xMatrix<float> xMatrixFloat;








typedef xMatrix<int> xMatrixInt;








typedef xMatrix<unsigned int> xMatrixUInt;








typedef xMatrix<__int64> xMatrixInt64;








typedef xMatrix<unsigned __int64> xMatrixUInt64;








//阵列








typedef xArray<bool> xArrayBool;








typedef xArray<char> xArrayChar;








typedef xArray<double> xArrayDouble;








typedef xArray<float> xArrayFloat;








typedef xArray<int> xArrayInt;








typedef xArray<unsigned int> xArrayUInt;








typedef xArray<__int64> xArrayInt64;








typedef xArray<unsigned __int64> xArrayUInt64;








//浮点数








typedef xDouble_Float<double>

xDouble;








typedef xDouble_Float<float>

xFloat;








//整数








typedef xinterger<int>

xInt;








typedef xinterger<unsigned int>

xUInt;








typedef xinterger<__int64>

xInt64;








typedef xinterger<unsigned __int64>

xUInt64;






最后开发包装接口mxWrap 。mxWrap 的构造函数提供了从标量、矩阵、阵列到字符的封装。根据不同的数据类型动态创建数据类型,从而实现了用

单一接口类来操作不同数据类型。下面将逐一介绍每个类的实现情况。

1.






ImxArray


一组MATLAB和 <wbr>C++数据交换类的设计

ImxArray 是数据接口类,主要成员数据有三个:

mxArray *m_pArray;

int






m_dataType;

char




m_szTypeName[64];

(其中 mxArray 是 MATLAB C API 的主要数据类型,通过 MATLAB C API 可以实现数据交互。具体使用情况可以参考 MATLAB HELP 。)

m_pArray 是存放 MATLAB 数据的指针, m_pArray 可以存放 MATLAB 中所有的数据,包括标量、矩阵、 STRUCT 和 CELL 等类型数据,通过 CLASSID 来标示数据类型,通过获取数据维数来标示是标量,矩阵还是阵列。可用的 CLASSID 列表如下:



typedef enum









{



















mxUNKNOWN_CLASS = 0,



















mxCELL_CLASS,



















mxSTRUCT_CLASS,



















mxLOGICAL_CLASS,



















mxCHAR_CLASS,



















mxVOID_CLASS,



















mxDOUBLE_CLASS,



















mxSINGLE_CLASS,



















mxINT8_CLASS,



















mxUINT8_CLASS,



















mxINT16_CLASS,



















mxUINT16_CLASS,



















mxINT32_CLASS,



















mxUINT32_CLASS,



















mxINT64_CLASS,



















mxUINT64_CLASS,



















mxFUNCTION_CLASS,



















mxOPAQUE_CLASS,



















mxOBJECT_CLASS,
















#if defined(_LP64) || defined(_WIN64)



















mxINDEX_CLASS = mxUINT64_CLASS,
















#else



















mxINDEX_CLASS = mxUINT32_CLASS,
















#endif



















mxSPARSE_CLASS = mxVOID_CLASS













}







本文封装了的数据类型包含了大部分 MATLAB 的数据类型 :

int32,int64,single,double,char,bool,string,struct,uint32,uint64.

未涉及的数据类型有 :

mxCELL_CLASS,mxFUNCTION_CLASS,mxOPAQUE_CLASS, mxOBJECT_CLASS 。

m_dataType 标示数据类型:

//matlab 数据类型 mxarray 封装



  1. //matlab数据类型mxarray封装







  2. #define


    MX_DATA_DOUBLE











    1

    //double







  3. #define


    MX_DATA_FLOAT












    2

    //double







  4. #define


    MX_DATA_BOOL













    3

    //bool







  5. #define


    MX_DATA_INT














    4

    //bool







  6. #define


    MX_DATA_UINT













    5

    //bool







  7. #define


    MX_DATA_INT64












    6

    //bool







  8. #define


    MX_DATA_UINT64











    7

    //bool







  9. #define


    MX_DATA_STRING











    8

    //string







  10. #define


    MX_DATA_NUMRIC_MATRIX




    9

    //数值矩阵







  11. #define


    MX_DATA_NUMRIC_ARRAY





    10

    //数值阵列







  12. #define


    MX_DATA_STRUCT











    12

    //结构体










  13. //matrix







  14. #define


    MX_DATA_MATRIX_DOUBLE











    21

    //double







  15. #define


    MX_DATA_MATRIX_FLOAT












    22

    //double







  16. #define


    MX_DATA_MATRIX_BOOL













    23

    //bool







  17. #define


    MX_DATA_MATRIX_INT














    24

    //bool







  18. #define


    MX_DATA_MATRIX_UINT













    25

    //bool







  19. #define


    MX_DATA_MATRIX_INT64












    26

    //bool







  20. #define


    MX_DATA_MATRIX_UINT64











    27

    //bool







  21. #define


    MX_DATA_MATRIX_STRING











    28

    //string







  22. #define


    MX_DATA_MATRIX_STRUCT











    29

    //结构体










  23. //array







  24. #define


    MX_DATA_ARRAY_DOUBLE











    31

    //double







  25. #define


    MX_DATA_ARRAY_FLOAT












    32

    //double







  26. #define


    MX_DATA_ARRAY_BOOL













    33

    //bool







  27. #define


    MX_DATA_ARRAY_INT














    34

    //bool







  28. #define


    MX_DATA_ARRAY_UINT













    35

    //bool







  29. #define


    MX_DATA_ARRAY_INT64












    36

    //bool







  30. #define


    MX_DATA_ARRAY_UINT64











    37

    //bool







  31. #define


    MX_DATA_ARRAY_STRING











    38

    //string








  32. #define


    MX_DATA_ARRAY_STRUCT











    39

    //结构体












virtual mxArray* GetArray(){ return m_pArray;}

virtual bool




SetArray(mxArray* pArray,bool bCopy=0){ return 1;};

GetArray 和 SetArray 未设置数据和获取数据的接口。 SetArray 带一个参数 bCopy 标示是否拷贝一份输入参数 pArray ,当 bCopy=0 是 ImxAray 对象将指向 pArray 所标示的数据,此时不能调用 mxDestroyArray 销毁 pArray ,否则将出错;若 bCopy=1 , ImxAray 对象将拥有一份独立的 pArray 的拷贝。 ImxAray 一般不单独使用,而是通过 mxWrap 来调用, mxWrap 定义了一系列含不同参数的构造函数来生成特定类型的数据,具体可参考 mxWrap 的实现部分。

2.xBool 布尔类型


一组MATLAB和 <wbr>C++数据交换类的设计

3.xDouble_Float<T> 浮点型



一组MATLAB和 <wbr>C++数据交换类的设计

浮点型数据分为实数和复数, IsComplex 可判断数据类型。构造函数如下:

xDouble_Float(T valReal=0.0,T valImg=0,bool bComplex=0);

通过 bComplex 设置数据是实数还是复数。数据操作函数如下:

//real





T GetRealData();





void


SetRealData(T val);





//img





T GetImgData();





void


SetImgData(T val);



4. xinterger<T> 整型


一组MATLAB和 <wbr>C++数据交换类的设计

5.string 字符串


一组MATLAB和 <wbr>C++数据交换类的设计

6.xMatrix<T> 矩阵


一组MATLAB和 <wbr>C++数据交换类的设计

模板实例化如下:



// 矩阵










typedef xMatrix<bool> xMatrixBool;









typedef xMatrix<char> xMatrixChar;







typedef xMatrix<double> xMatrixDouble;









typedef xMatrix<float> xMatrixFloat;









typedef xMatrix<int> xMatrixInt;









typedef xMatrix<unsigned int> xMatrixUInt;









typedef xMatrix<__int64> xMatrixInt64;









typedef xMatrix<unsigned __int64> xMatrixUInt64;








// 矩阵








typedef xMatrix<bool> xMatrixBool;






typedef xMatrix<char> xMatrixChar;






typedef xMatrix<double> xMatrixDouble;






typedef xMatrix<float> xMatrixFloat;






typedef xMatrix<int> xMatrixInt;






typedef xMatrix<unsigned int> xMatrixUInt;






typedef xMatrix<__int64> xMatrixInt64;






typedef xMatrix<unsigned __int64> xMatrixUInt64;

矩阵的主要参数是行和列, GetR() 获得行数; GetC() 获取列数。构造函数如下:







xMatrix(mwSize m=1, mwSize n=1, T *valReal=0,T *valImg=0,mxComplexity flag=mxREAL);

这里需要注意几点:

1.






matlab 和 c++ 的数据存储方式有差别, matlab 的矩阵是按列存储的,所有在数据交互是需注意数据的格式。当输入矩阵时,比如:

view plaincopy to clipboardprint?

double

dm1[]=//2*3




{









11,12,13,








21,22,23,




};





xMatrixDouble

dm(2,3,dm1);



输入数据是

11 12 13

21 22 23

而在 matlab 中矩阵是这样的:

11 13 22

12 21 23

即先从输入数据顺序读入: 11,12,13,21,22,23 ,,然后按列放置

先放置第一列

11

12

第二列:

11 13

12 21

第三列:

11 13 22

12 21 23



可以调用 static void

C2Mat(T* c_input,int r,int c,T*m_outPut); 来把 C 格式转换为 matlab 格式。这样你所输入的矩阵将和 MATLAB 空间中的矩阵一致:



double

dm1[]=//2*5








{











11,12,13,14,15,











21,22,23,24,25








};








xMatrixDouble::C2Mat(dm1,2,5,dm1);








xMatrixDouble

dm(2,5,dm1);








cout<<“\nmatrix\n”;








for (int i=0;i<dm.GetR();i++)








{











for (int k=0;k<dm.GetC();k++)











{















cout<<dm.GetRealAt(i,k)<<”

“;











}











cout<<endl;













}














double

dm1[]=//2*5









{













11,12,13,14,15,












21,22,23,24,25









};









xMatrixDouble::C2Mat(dm1,2,5,dm1);









xMatrixDouble

dm(2,5,dm1);









cout<<“\nmatrix\n”;









for (int i=0;i<dm.GetR();i++)









{













for (int k=0;k<dm.GetC();k++)












{
















cout<<dm.GetRealAt(i,k)<<”

“;












}












cout<<endl;












}


一组MATLAB和 <wbr>C++数据交换类的设计

2. 只有 double 和 float 拥有复数类型,所有对于其他矩阵,复数没有意义,所以在构造函数初始化时: xMatrix(mwSize m=1, mwSize n=1, T *valReal=0,T *valImg=0,mxComplexity flag=mxREAL) ,参数 valImg=0 , flag=mxREAL 。

7. xArray<T> 阵列


一组MATLAB和 <wbr>C++数据交换类的设计

所谓阵列就是指维数在二维以上的数据,

int

GetDimSize(); 获取维数

int

GetDim(int index ); 获取第几维的长度

int

GetDataSize(); 获取存放的总数据个数,即维数尺寸的乘积

矩阵时维数维二维的阵列,在数据类型设计中,原本是这样考虑的:先构建阵列维模板,然后通过将阵列的维数设置为两维,从而派生出矩阵类,矩阵类的所有操作都委托给二维阵列,将矩阵的行数和列数设置为 1 ,从而派生出标量类,操作委托给行数和列数为 1 的矩阵,由于这些类都是模板类,所有对模板进行实例化可以得到各种不同的类型。

后来参考了 MATLAB C API ,发现 API 里对不同的数据类型的都有各自的处理函数,通过阵列函数来操作矩阵或者标量或许有些大材小用,影响性能。阵列的数据存放和矩阵一样是按列来的,对于三维以上的阵列,数据的输入可能就比较复杂了,处理时可要细心。 MATLAB 提供了 API 来进行数据转换,可以参考 HELP.

void

GetRealData(T*bufferReal,int buffersize);






void

SetRealData(T*bufferReal,int buffersize);






void

GetImgData( T*bufferImg, int buffersize);






void

SetImgData( T*bufferImg, int buffersize);






通过调用 GetRealData 可获取实部数据,注意缓存区大小要够,即 buffersize>= GetDataSize().

调用 SetRealData 设置数据。虚部处理一样。

8.xStruct 结构体


一组MATLAB和 <wbr>C++数据交换类的设计

结构体由若干数据项组成,每个数据项包括名称和数据,和 C 语言的结构体是一样的, xStruct 可以增加数据相或者删除数据项 .

int





GetFieldCount();// 获得数据项数量




bool




AddField( const char *fieldname);// 增加一个数据项,




bool




RemoveField( int index);// 删除数据项




mxWrap

*GetField( mwIndex i);// 获取每个数据项的数据




std::string

GetFieldName(mwIndex i);// 获得某项数据项的名称




bool





SetField(mwIndex i,mxWrap *value);// 设置数据




bool




SetField(std::string item_name,mxWrap *value);



9.mxWrap


一组MATLAB和 <wbr>C++数据交换类的设计


mxWrap 主要有多个不同参数的构造函数,通过传递不同的参数可以构造出不同的数据类型出来,包括标量、矩阵、阵列和结构体。和 matlab 的交互过程可简化为:

写入变量、执行计算和提取结果。使用 mxWrap 来写入变量和提取结果客大大简化交互程序。

举例子如下:







矩阵 A=[1 2 3;4 5 6; 7 8 9;]; B=[11 21 31;41 51 61; 71 81 91;]; 求 矩阵 C=A*B;

代码如下:


CMatlabEngine

g;//gobal engine







g.OpenEngine();;//open engine












//MATRIX A







double

A[]=







{










1,2,3,










4,5,6,










7,8,9







};







xMatrixDouble::C2Mat(A,3,3,A);












//MATRIX B







double

B[]=







{










11,21,31,










41,51,61,










71,81,91








};







xMatrixDouble::C2Mat(B,3,3,B);












//VAR A and B







mxWrap

a(3,3,A);







mxWrap

b(3,3,B);












//PUT VAR







g.PutVar(“A”,a.GetArray());







g.PutVar(“B”,b.GetArray());












//CAL







g.EvalString(“C=A*B”);












//get val







mxWrap c;







g.GetVar(“C”,&c);







//disp data












xMatrixDouble*ptr=(xMatrixDouble*)c.GetArrayInterface();







cout<<“C=A*B\n”;







for (int i=0;i<ptr->GetR();i++)







{









for (int j=0;j<ptr->GetC();j++)










{



















cout<<ptr->GetRealAt(i,j)<<”

“;
















} cout<<endl;







}







g.CloseEngine();//close





一组MATLAB和 <wbr>C++数据交换类的设计

10.xFile


一组MATLAB和 <wbr>C++数据交换类的设计

Mat 文件是 matlab 特有的数据存储文件类型,将变量存储于 mat 文件可以很方便进行数据交互。 MATLAB 提供了一组 API 进行 mat 文件操作,这些 API 以 mat 开头,如 matOpen 。

xFile 封装类 mat 文件的操作。

调用 bool

Open(char *matFile,char* mode=”u”); 打开一个 mat 文件, mode 为操作方式,可以为 mode=”r” 读 , “u” 读写 ,”w” 写 ,”w4″,”wL”,”wz” 压缩模式。

mxWrap* GetArray(char*name,bool bCopy=1); 获取特定名称的变量

void



SetArray(char*name,mxWrap*pArray); 添加变量,若该变量已经存在,则会更新变量

int




GetVarCount();// 获得变量的个数

mxWrap* GetArray(int index,std::string*nameOut=NULL,bool bCopy=1);

遍历所有遍历:

for (int i=0;i<GetVarCount();i++)

{








std::string name;







mxWrap*ptr=GetArray(i,&name);

}

一个写mat文件的例子:





cout<<“===========写mat文件测试====================\n”;









xFile f;









mxWrap d(12.0);









if(0==f.Open(“D:\\write.mat”,”w”))









{













cout<<“打开文件:D:\\write.mat失败\n”;













return ;









}



















xDouble v1(123.0);









f.SetArray(“double_v”,&mxWrap(v1.GetArray()));









//替换测试









xString v11(“double_v——通过测试”);









f.SetArray(“double_v”,&mxWrap(v11.GetArray()));



















xFloat v2(223.0);









f.SetArray(“xFloat_v”,&mxWrap(v2.GetArray()));



















xString v3(“xString”);









f.SetArray(“xString_v”,&mxWrap(v3.GetArray()));



















//替换测试









xString v31(“xString——通过测试”);









f.SetArray(“xString_v”,&mxWrap(v3.GetArray()));



















xBool v4(1);









f.SetArray(“xBool_v”,&mxWrap(v4.GetArray()));



















xInt v5(1569);









f.SetArray(“xInt_v”,&mxWrap(v5.GetArray()));





























xUInt v6(136);









f.SetArray(“xUInt_v”,&mxWrap(v6.GetArray()));



















xInt64 v7(64);









f.SetArray(“xInt64_v”,&mxWrap(v7.GetArray()));



















xUInt64 v8(164);









f.SetArray(“xUInt64_v”,&mxWrap(v8.GetArray()));



















double dt[8]={1,2,3,4,5,6,7,8};









xMatrixDouble v9(2,4,dt);









f.SetArray(“xMatrixDouble_v”,&mxWrap(v9.GetArray()));





























mwSize dm[3]={2,2,2};









xArrayDouble v10(3,dm,dt);









f.SetArray(“xArrayDouble_v”,&mxWrap(v10.GetArray()));
























xStruct

xs;









xs.AddField(“sam”);









xs.AddField(“love”);









xs.SetField(0,new mxWrap(120.364));









xs.SetField(1,new mxWrap(“The type_info class describes type information generated within the program by the compiler. Objects of this class effectively store a pointer to a name for the type and an encoded value suitable for comparing two types for equality or collating order. The encoding rules and collating sequence for types are unspecified and may differ between programs.”));









f.SetArray(“xstruct”,&mxWrap(xs.GetArray()));



















///删除变量









if(f.RemoveVar(“xInt_v”))cout<<“成功删除变量!\n”;









if(f.RemoveVar(“xMatrixDouble_v”))cout<<“成功删除变量!\n”;









if(0==f.RemoveVar(“不存在的名称”))













cout<<“删除不存在变量失败!\n”;



















f.Close();











}





将得到的mat文件调入matlab查看:


一组MATLAB和 <wbr>C++数据交换类的设计

下面举例如何使用该程序

例一:

输入任意y=f(x),求y对x的n阶导数,结果存放到字符串中取得,并计算原函数和n阶导数在x0处的值。





CMatlabEngine

eng;







eng.OpenEngine();














char tmp[200];//表达式







char tmp1[200];







mxWrap

df;//导数表达式







mxWrap

val;//原函数值







mxWrap

dfval;//导数值







xDouble

vx0;//x0 输入







double

x0=0;







int n=1;//导数阶数
















strcpy(tmp,”syms x;”);







eng.EvalString(tmp);














cout<<“输入表达式:”;







cin>>tmp;







cout<<“输入导数阶数:”;







cin>>n;







cout<<“输入x0:”;







cin>>x0;







vx0.SetRealData(x0);







while( tmp[0] != ‘q’ )







{











eng.PutVar(“x0”,vx0.GetArray());//input x0










//get express










sprintf(tmp1,”%s;z1=char(diff(y,%d)),z=char(z1),val=subs(y,x,x0),dfval=subs(z,x,x0)”,tmp,n);










//cal










eng.EvalString(tmp1);










//get val










eng.GetVar(“z”,&df);//n阶导数表达式










eng.GetVar(“val”,&val);//原函数在x0处的数值










eng.GetVar(“dfval”,&dfval);//n阶导数在x0处的数值










cout<<“—————————matlab output—————-\n”;










cout<<eng.GetOutPut()<<endl;










cout<<“———————————————————\n”;










cout<<“—————————求导结果—————-\n”;










xString*ps=(xString*)df.GetArrayInterface();










cout<<“求导结果:”<<ps->GetString().data()<<endl;










xDouble*pd=(xDouble*)val.GetArrayInterface();










cout<<“原函数在x0处的值:”<<pd->GetRealData()<<endl;










pd=(xDouble*)dfval.GetArrayInterface();










cout<<“原函数导n阶数在x0处的值:”<<pd->GetRealData()<<endl;










cout<<“—————————————————-\n”;










cout<<“输入表达式:”;










cin>>tmp;










cout<<“输入导数阶数:”;










cin>>n;










cout<<“输入x0:”;










cin>>x0;










vx0.SetRealData(x0);







}







eng.CloseEngine();

编译运行:

输入 y=x^2+x








n=1








x0=10

输出:







dff=2*x+1







val=110







dfval=21


一组MATLAB和 <wbr>C++数据交换类的设计

例2:mat文件操作

这个例子将展示如何用xFile读取mat文件和写mat文件

A=[1 2 3;4 5 6;7 8 9];

B=”南京航空航天大学 san visualsan@yahoo.cn”;

C.name=”san”;C.address=”NUAA”;C.score=99.9;C.matrix=[12

22 32];

D=123.00

E=100;

将A,B,C,D,E写入d:\\result.mat


int dA[]=






{









1 ,2 ,3,









4 ,5 ,6,









7 ,8 ,9






};






xMatrixInt::C2Mat(dA,3,3,dA);











mxWrap A(3,3,dA);






mxWrap B(“南京航空航天大学 san visualsan@yahoo.cn”);











xStruct* xs=new xStruct;






//add field






xs->AddField(“name”);






xs->AddField(“address”);






xs->AddField(“score”);






xs->AddField(“matrix”);











mxWrap*ptr;






ptr=new mxWrap(“san”);






xs->SetField(0,ptr);//add name






ptr=new mxWrap(“NUAA”);






xs->SetField(1,ptr);//add address






ptr=new mxWrap(99.9);






xs->SetField(2,ptr);//add score






double m[]={12 ,22, 32};






xMatrixDouble::C2Mat(m,1,3,m);






ptr=new mxWrap(1,3,m);;






xs->SetField(3,ptr);//add matrix
















mxWrap

C(xs);






mxWrap

D(123.00);






mxWrap

E(100);











xFile

xf;






//OPEN FILE






xf.Open(“d:\\result.mat”,”w”);











//ADD VAR






xf.SetArray(“A”,&A);






xf.SetArray(“B”,&B);






xf.SetArray(“C”,&C);






xf.SetArray(“D”,&D);






xf.SetArray(“E”,&E);











//CLOSE






xf.Close();




将result.mat调入matlab查看:


一组MATLAB和 <wbr>C++数据交换类的设计


从d:\result.mat读取所有变量并显示:



template<class T>






struct


disp_matrix//矩阵打印






{









void operator()(ImxArray*m)









{













xMatrix<T>*pm=(xMatrix<T>*)m;













cout<<“==============matrix===========\n”;













cout<<m->GetTypeName()<<endl;













for (int i=0;i<pm->GetR();i++)













{

















for (int j=0;j<pm->GetC();j++)

















{





















cout<<pm->GetRealAt(i,j)<<”

“;

















}

















cout<<endl;































}









}






};











template<class T>






struct


disp_array//阵列打印






{









void operator()(ImxArray*m){









std::string str=typeid(T).name();









cout<<str.data()<<endl;









xArray<T>*pm=(xArray<T>*)m;









cout<<“============== array===========\n”;









T *dt=new T[pm->GetDataSize()];









pm->GetRealData(dt,pm->GetDataSize());









for (int k=0;k<pm->GetDataSize();k++)









{













cout<<dt[k]<<” “;























}












cout<<endl;









delete dt;









}






};






void

display_data(ImxArray*ptr,std::string& n)//数据打印






{









if(!ptr)













return ;









//double









if(ptr->GetType()==MX_DATA_DOUBLE)









{













cout<<n.data()<<”

=====double======


“<<((xDouble*)ptr)->GetRealData()<<endl;









}









//FLOAT









if(ptr->GetType()==MX_DATA_FLOAT)









{













cout<<n.data()<<”

=====float======


“<<((xFloat*)ptr)->GetRealData()<<endl;









}









//string









if(ptr->GetType()==MX_DATA_STRING)









{













cout<<n.data()<<”

=====string======


“<<((xString*)ptr)->GetString().data()<<endl;









}









//bool









if(ptr->GetType()==MX_DATA_BOOL)









{













cout<<n.data()<<”

=====bool======


“<<((xBool*)ptr)->GetData()<<endl;









}









//int









if(ptr->GetType()==MX_DATA_INT)









{













cout<<n.data()<<”

=====uint======


“<<((xInt*)ptr)->GetData()<<endl;









}









//unsigned int









if(ptr->GetType()==MX_DATA_UINT)









{













cout<<n.data()<<”

=====int64======


“<<((xUInt*)ptr)->GetData()<<endl;









}









//int64









if(ptr->GetType()==MX_DATA_INT64)









{













cout<<n.data()<<”

=====uint64======


“;













printf(“%I64d\n”,((xInt64*)ptr)->GetData());









}









//unsigned int64









if(ptr->GetType()==MX_DATA_UINT64)









{













cout<<n.data()<<”

=====uint64======


“;













printf(“%I64u\n”,((xInt64*)ptr)->GetData());









}









// matrix









if(ptr->GetType()==MX_DATA_MATRIX_BOOL)









{













disp_matrix<bool>()(ptr);









}









if(ptr->GetType()==MX_DATA_MATRIX_STRING)









{













disp_matrix<char>(ptr);









}









if(ptr->GetType()==MX_DATA_MATRIX_DOUBLE)









{













disp_matrix<double>()(ptr);









}









if(ptr->GetType()==MX_DATA_MATRIX_FLOAT)









{













disp_matrix<float>()(ptr);









}









if(ptr->GetType()==MX_DATA_MATRIX_INT)









{













disp_matrix<int>()(ptr);









}









if(ptr->GetType()==MX_DATA_MATRIX_UINT)









{













disp_matrix<unsigned int>()(ptr);









}









if(ptr->GetType()==MX_DATA_MATRIX_INT64)









{













cout<<“__int64\n”;













//disp_matrix<__int64>(ptr);









}









if(ptr->GetType()==MX_DATA_MATRIX_INT64)









{













cout<<“unsigned __int64\n”;













//disp_matrix<unsigned __int64>(ptr);









}









// array









if(ptr->GetType()==MX_DATA_ARRAY_BOOL)









{













disp_array<bool>()(ptr);









}









if(ptr->GetType()==MX_DATA_ARRAY_STRING)









{













disp_array<char>()(ptr);









}









if(ptr->GetType()==MX_DATA_ARRAY_DOUBLE)









{













disp_array<double>()(ptr);









}









if(ptr->GetType()==MX_DATA_ARRAY_FLOAT)









{













disp_array<float>()(ptr);









}









if(ptr->GetType()==MX_DATA_ARRAY_INT)









{













disp_array<int>()(ptr);









}









if(ptr->GetType()==MX_DATA_ARRAY_UINT)









{













disp_array<unsigned int>()(ptr);









}









if(ptr->GetType()==MX_DATA_ARRAY_INT64)









{













cout<<“__int64\n”;













//disp_matrix<__int64>(ptr);









}









if(ptr->GetType()==MX_DATA_ARRAY_INT64)









{













cout<<“unsigned __int64\n”;













//disp_matrix<unsigned __int64>(ptr);









}



















//struct









if (ptr->GetType()==MX_DATA_STRUCT)









{













cout<<“———————struct———————————————-\n”;













xStruct*ps=(xStruct*)ptr;













for (int i=0;i<ps->GetFieldCount();i++)













{

















if(ps->GetField(i)->GetArrayInterface())





















display_data(ps->GetField(i)->GetArrayInterface(),n);













}













cout<<“———————struct———————————————-\n”;









}






}






void test4()






{









xFile

xf;









if (xf.Open(“d:\\result.mat”,”r”))









{













cout<<“变量个数:”<<xf.GetVarCount()<<endl;













std::vector<mxWrap*>

var;













std::vector<std::string>

vname;













for (int i=0;i<xf.GetVarCount();i++)













{

















std::string name;

















var.push_back(xf.GetArray(i,&name,1));

















vname.push_back(name);

















//输出名称

















printf(“var name(-)= s\n”,i+1,name.data());













}


















//输出每个变量













for(i=0;i<var.size();i++)













{

















display_data(var[i]->GetArrayInterface(),vname[i]);













}









}






}




结果如下:


一组MATLAB和 <wbr>C++数据交换类的设计