matlab与c(c++)混合编程

说了c++,其实实质上是matlab与c的混合编程。因为matlab提供的东西几个函数就能搞定了,不必要动辄用到C++的特性。matlab与c交互有几种方式,我认为可分为两类:一类是c从matlab里取东西,一类是matlab从c里取东西。这两类的内容在matlab的User’s Guide里都有,在C/C++ and Fortran API Reference中。

我今天将要在c中将数组数据放到matlab矩阵类型中,并将这些矩阵写入mat数据文件。用到的功能在matlab的MAT-File LibraryMX Matrix Library中,这两个功能的函数分别在/MATLAB/R2010b/bin/win32/libmat.dll和/MATLAB/R2010b/bin/win32/libmx.dll中。对应的头文件为/MATLAB/R2010b/extern/include/mat.h和/MATLAB/R2010b/extern/include/matrix.h,对应lib文件为/MATLAB/R2010b/extern/lib/win32/microsoft/libmat.lib和/MATLAB/R2010b/extern/lib/win32/microsoft/libmx.lib。上面说的都是在vs系列编译环境中需要的,有了这些我们就可以安安稳稳的使用matlab提供的这些API了。

下面的文章清楚的说明了如何使用matlab提供的函数生成mxArray矩阵以及将矩阵放在mat文件中http://www.mathworks.com/help/techdoc/matlab_external/f39876.html。并且这里还有一个例子用来很好的说明问题,也可以用来测试编译环境是否已经配好http://www.mathworks.com/help/techdoc/matlab_external/rmvd_matlablink__33.html

然后就是我简单总结一下整个过程。整个过程在一段完整的代码上进行讲述。

   1: int main()
   2: {
   3:     MATFile *pmat;
   4:     mxArray *pa1, *pa2, *pa3;
   5:     double data[9] = { 1.0, 4.0, 7.0, 2.0, 5.0, 8.0, 3.0, 6.0, 9.0 };
   6:     const char *file = "mattest.mat";
   7:     char str[BUFSIZE];
   8:     int status;
   9:  
  10:     printf("Creating file %s.../n/n", file);
  11:     pmat = matOpen(file, "w");
  12:     if (pmat == NULL)
  13:     {
  14:         printf("Error creating file %s/n", file);
  15:         printf("(Do you have write permission in this directory?)/n");
  16:         return(EXIT_FAILURE);
  17:     }
  18:  
  19:     pa1 = mxCreateDoubleMatrix(3,3,mxREAL);
  20:     if (pa1 == NULL)
  21:     {
  22:         printf("%s : Out of memory on line %d/n", __FILE__, __LINE__);
  23:         printf("Unable to create mxArray./n");
  24:         return(EXIT_FAILURE);
  25:     }
  26:  
  27:     pa2 = mxCreateDoubleMatrix(3,3,mxREAL);
  28:     if (pa2 == NULL)
  29:     {
  30:         printf("%s : Out of memory on line %d/n", __FILE__, __LINE__);
  31:         printf("Unable to create mxArray./n");
  32:         return(EXIT_FAILURE);
  33:     }
  34:     memcpy((void *)(mxGetPr(pa2)), (void *)data, sizeof(data));
  35:     int k=0;
  36:     double* temp;
  37:     temp=(double*)mxGetData(pa2);
  38:     for(k=0;k<6;k++){
  39:         temp++;
  40:     }
  41:  
  42:     pa3 = mxCreateString("MATLAB: the language of technical computing");
  43:     if (pa3 == NULL)
  44:     {
  45:         printf("%s :  Out of memory on line %d/n", __FILE__, __LINE__);
  46:         printf("Unable to create string mxArray./n");
  47:         return(EXIT_FAILURE);
  48:     }
  49:  
  50:     status = matPutVariable(pmat, "LocalDouble", pa1);
  51:     if (status != 0)
  52:     {
  53:         printf("%s :  Error using matPutVariable on line %d/n", __FILE__, __LINE__);
  54:         return(EXIT_FAILURE);
  55:     }
  56:  
  57:     status = matPutVariableAsGlobal(pmat, "GlobalDouble", pa2);
  58:     if (status != 0)
  59:     {
  60:         printf("Error using matPutVariableAsGlobal/n");
  61:         return(EXIT_FAILURE);
  62:     }
  63:  
  64:     status = matPutVariable(pmat, "LocalString", pa3);
  65:     if (status != 0)
  66:     {
  67:         printf("%s :  Error using matPutVariable on line %d/n", __FILE__, __LINE__);
  68:         return(EXIT_FAILURE);
  69:     }
  70:  
  71:     /*
  72:      * Ooops! we need to copy data before writing the array.  (Well,
  73:      * ok, this was really intentional.) This demonstrates that
  74:      * matPutVariable will overwrite an existing array in a MAT-file.
  75:      */
  76:     memcpy((void *)(mxGetPr(pa1)), (void *)data, sizeof(data));
  77:     status = matPutVariable(pmat, "LocalDouble", pa1);
  78:     if (status != 0)
  79:     {
  80:         printf("%s :  Error using matPutVariable on line %d/n", __FILE__, __LINE__);
  81:         return(EXIT_FAILURE);
  82:     }
  83:  
  84:     /* clean up */
  85:     mxDestroyArray(pa1);
  86:     mxDestroyArray(pa2);
  87:     mxDestroyArray(pa3);
  88:  
  89:     if (matClose(pmat) != 0)
  90:     {
  91:         printf("Error closing file %s/n",file);
  92:         return(EXIT_FAILURE);
  93:     }
  94:  
  95:     /*
  96:      * Re-open file and verify its contents with matGetVariable
  97:      */
  98:     pmat = matOpen(file, "r");
  99:     if (pmat == NULL)
 100:     {
 101:         printf("Error reopening file %s/n", file);
 102:         return(EXIT_FAILURE);
 103:     }
 104:  
 105:     /*
 106:      * Read in each array we just wrote
 107:      */
 108:     pa1 = matGetVariable(pmat, "LocalDouble");
 109:     if (pa1 == NULL)
 110:     {
 111:         printf("Error reading existing matrix LocalDouble/n");
 112:         return(EXIT_FAILURE);
 113:     }
 114:     if (mxGetNumberOfDimensions(pa1) != 2)
 115:     {
 116:         printf("Error saving matrix: result does not have two dimensions/n");
 117:         return(EXIT_FAILURE);
 118:     }
 119:  
 120:     pa2 = matGetVariable(pmat, "GlobalDouble");
 121:     if (pa2 == NULL)
 122:     {
 123:         printf("Error reading existing matrix GlobalDouble/n");
 124:         return(EXIT_FAILURE);
 125:     }
 126:     if (!(mxIsFromGlobalWS(pa2)))
 127:     {
 128:         printf("Error saving global matrix: result is not global/n");
 129:         return(EXIT_FAILURE);
 130:     }
 131:  
 132:     pa3 = matGetVariable(pmat, "LocalString");
 133:     if (pa3 == NULL)
 134:     {
 135:         printf("Error reading existing matrix LocalString/n");
 136:         return(EXIT_FAILURE);
 137:     }
 138:  
 139:     status = mxGetString(pa3, str, sizeof(str));
 140:     if(status != 0)
 141:     {
 142:         printf("Not enough space. String is truncated.");
 143:         return(EXIT_FAILURE);
 144:     }
 145:     if (strcmp(str, "MATLAB: the language of technical computing"))
 146:     {
 147:         printf("Error saving string: result has incorrect contents/n");
 148:         return(EXIT_FAILURE);
 149:     }
 150:  
 151:     /* clean up before exit */
 152:     mxDestroyArray(pa1);
 153:     mxDestroyArray(pa2);
 154:     mxDestroyArray(pa3);
 155:  
 156:     if (matClose(pmat) != 0)
 157:     {
 158:         printf("Error closing file %s/n",file);
 159:         return(EXIT_FAILURE);
 160:     }
 161:     printf("Done/n");
 162:     return(EXIT_SUCCESS);
 163: }

一、创建mxArray矩阵变量。

   1: double data[9] = { 1.0, 4.0, 7.0, 2.0, 5.0, 8.0, 3.0, 6.0, 9.0 };
   2: mxArray *pa2;
   3: pa2 = mxCreateDoubleMatrix(3,3,mxREAL);
   4: memcpy((void *)(mxGetPr(pa2)), (void *)data, sizeof(data));

这段代码是从完整代中截取的,内容为创建mxArray矩阵,并将c格式的数据(必须为double类型的数组)放到mxArray矩阵中,主要用到了函数mxCreateDoubleMatrix()。这段代码使用这个函数创建了一个3*3的实数密集矩阵(相对于稀疏矩阵),并将矩阵的首地址赋给pa2(注:矩阵中元素默认初始值为0,类型相当于c中的double)。然后使用mxGetPr()找到这个矩阵的数据部分,再使用c的memcpy函数将原始数据拷贝到这块内存空间中。使用memcpy要小心点,这直接对内存的操作最容易出问题了。这里还有一个需要注意的地方,就是用memcpy将整块内存中的数据拷到mxArray中后,这个mxArray矩阵也就是在matlab中的矩阵按列优先排列数据。为了表述清晰,我画个图给大家看看。

image

二、将mxArray矩阵变量放到mat数据文件中。

   1: const char *file = "mattest.mat";
   2: MATFile *pmat;
   3: pmat = matOpen(file, "w");
   4: int status;
   5: status = matPutVariableAsGlobal(pmat, "GlobalDouble", pa2);

程序先要创建一个MATFile结构,这个结构存储了关于mat文件的信息。使用matOpen命令打开指定的mat文件,若参数为"w”则为写,即可以通过pmat变量向文件里写东西。若使用matOpen命令打开的mat文件不存在,则新建此文件。有了mat文件的框框,接下来就是要往文件里写东西了。matPutVariableAsGlobal()和matPutVariable()命令差不多,具体差别还没研究,到时候再说,本文使用它们并没有什么区别。matPutVariableAsGlobal函数将pa2这个c中的mxArray结构用GlobalDouble的变量名写进了pmat指向的mattest.mat文件,即当我们在matlab中加载mattest.mat这个文件时,全局工作区中会出现GlobalDouble这个变量。mat文件中就有一个数据了,我们可以再向其中写入矩阵数据。这里需要提醒大家的是,如果写入的变量名在mat文件中已经存在,则新的变量会覆盖原来老的变量,这个同matlab中的情况一样,所以大家要小心。

三、处理后事。

   1: mxDestroyArray(pa2);
   2: matClose(pmat);

当然我们不能用完了mat文件就拍屁股走人了,还有善一下后的。mxDestroyArray函数释放刚才mxCreateDoubleMatrix申请的空间。matClose则负责关闭刚才打开的mat文件。这样就可以了。

以上这些就是整个的处理过程,但三步中引用的代码都是极为简单的,实际中还要加入一些判断条件,以免产生错误。如mxCreateDoubleMatrix可能没申请到空间,matOpen可能打不开文件等。剩下的大家就自己看上面给出的文章领悟吧,希望大家都能早日大彻大悟。

参考文献:

[1] http://www.mathworks.com/help/techdoc/matlab_external/f39876.html

[2] http://www.mathworks.com/help/techdoc/matlab_external/f14500.html

[3] http://www.mathworks.com/matlabcentral/answers/2973-visual-studio-2010-and-mat-files

[4] http://www.cnblogs.com/strinkbug/archive/2007/04/24/725050.html

[5] http://hi.baidu.com/ruoxinjiu/blog/item/d11c3e1b073426ddad6e75af.html

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值