Visual Studio 2010中的C++程序调用matlab程序代码 混合编程

来源:互联网 发布:已备案域名购买转入 编辑:程序博客网 时间:2024/06/06 01:02

本文目的:用matlab语言编写的程序函数可以通过参数接口在C++程序中调用,通过使用matlab生成dll形式,用C/C++程序调用!!!

环境配置:

1、环境及其所用工具:Window 7系统   matlab2012b  VS2010

2、这里注意下安装顺序,在安装matlab之前,一定要有VS软件在操作系统中 .否则在生成dll过程中,会找不到VS情况存在。

下面用matlab 2012b生成.dll、.lib、.h文件:

[cpp] view plain copy
print?
  1. >>> mbuild -setup  
  2. Please choose your compiler for building standalone MATLAB applications:   
  3.    
  4. Would you like mbuild to locate installed compilers [y]/n? y  
  5.    
  6. Select a compiler:   
  7. [1] Lcc-win32 C 2.4.1 in C:\PROGRA~1\MATLAB\R2010b\sys\lcc   
  8. [2] Microsoft Visual C++ 2010 in C:\Program Files\Microsoft Visual Studio 10.0   
  9. [3] Microsoft Visual C++ 2008 SP1 in C:\Program Files\Microsoft Visual Studio 9.0   
  10.    
  11. [0] None   
  12.    
  13. Compiler: 2  
  14.    
  15. Please verify your choices:   
  16.    
  17. Compiler: Microsoft Visual C++ 2010    
  18. Location: C:\Program Files\Microsoft Visual Studio 10.0   
  19.    
  20. Are these correct [y]/n? y  
  21.    
  22. ****************************************************************************   
  23.   Warning: Applications/components generated using Microsoft Visual C++        
  24.            2010 require that the Microsoft Visual Studio 2010 run-time         
  25.            libraries be available on the computer used for deployment.         
  26.            To redistribute your applications/components, be sure that the      
  27.            deployment machine has these run-time libraries.                    
  28. ****************************************************************************   
  29.    
  30. Trying to update options file: C:\Users\IDM\AppData\Roaming\MathWorks\MATLAB\R2010b\compopts.bat   
  31. From template:              C:\PROGRA~1\MATLAB\R2010b\bin\win32\mbuildopts\msvc100compp.bat   
  32.    
  33. Done . . .   
以上为matlab中运行,主要是找到对应的VS版本。

然后,加入我们编写的.m文件为showimage.m,则:

[cpp] view plain copy
print?
  1. <span style="color: rgb(68, 68, 68); font-family: 'courier new'; font-size: 14px; line-height: 15.4px; background-color: rgb(238, 238, 238);">mcc -W cpplib:showimage -T link:lib showimage.m</span>  
  2. mcc是编译为C接口的动态链接库。-W lib是将showimage.m编译为名为showimage的动态链接库。  
  3.   
  4. 另一种使用csharedlib捆绑命令也是等价的:  
  5. mcc -B csharedlib:showimage showimage.m  
  6.   
  7. 之后会生成一堆dll、lib、.h、.c等文件。</span>  

参考链接:http://blog.csdn.net/xiaowei_cqu/article/details/7339356


通过以上步骤,你会得到在VS中要用到的动态库和静态库等文件。

下面要配置VS2010中的环境:


基本按照下面链接中的步骤进行了,执行完毕后,经测试并没有问题。


VS2010环境配置



并使用如下代码进行测试:

[cpp] view plain copy
print?
  1. #include "stdafx.h"  
  2. #include <iostream>  
  3. #include <stdio.h>  
  4. #include "libAdd.h"  
  5. #include "showimage.h"  
  6. #include "engine.h"  
  7.   
  8. #include <stdlib.h>  
  9. #include <string.h>  
  10. #include "matrix.h"  
  11.   
  12. using namespace std;  
  13.   
  14.   
  15. #define BUFSIZE 256  
  16.   
  17. int main()  
  18. {  
  19. if (!showimageInitialize())  
  20.     {  
  21.         return -1;  
  22.     }  
  23. //测试两个整数相加  
  24.     int a = 10;  
  25.     int b = 20;  
  26.     int c;  
  27.   
  28.     mwArray mwA(1,1,mxINT32_CLASS);  
  29.     mwArray mwB(1,1,mxINT32_CLASS);  
  30.     mwArray mwC(1,1,mxINT32_CLASS);  
  31.   
  32.     mwA.SetData(&a,1);  
  33.     mwB.SetData(&b,1);  
  34.     add(1, mwC, mwA, mwB);  
  35.     c = mwC.Get(1,1);  
  36.     cout<<"c = "<<c<<endl<<endl;  
  37.   
  38.     //测试两个double型矩阵相加  
  39.   
  40.     double da[2][2] = {1,2,3,4}, db[2][2] = {5,6,7,8};  
  41.     double dc[2][2];  
  42.     mwArray mwDA(2,2,mxDOUBLE_CLASS);  
  43.     mwArray mwDB(2,2,mxDOUBLE_CLASS);  
  44.     mwArray mwDC(2,2,mxDOUBLE_CLASS);  
  45.     mwDA.SetData(*da, 4);  
  46.     mwDB.SetData(*db, 4);  
  47.     add(1, mwDC, mwDA, mwDB);  
  48.     cout<<"dc = "<<endl;  
  49.     for(int i = 0; i < 2; i++)  
  50.     {  
  51.         for(int j = 0; j < 2; j++)  
  52.         {  
  53.             dc[i][j] = mwDC.Get(2,j+1,i+1);  
  54.   
  55.             cout<<"  "<<dc[i][j];  
  56.         }  
  57.         cout<<endl;  
  58.     }  
  59.     //自定义程序测试  
  60.     double ta[1][4] = {1,2,3,4};  
  61.     double tb[1][4] = {5,6,7,8};  
  62.     double tc[1][4];  
  63.   
  64.     mwArray mwTA(4,4,mxDOUBLE_CLASS);  
  65.     mwArray mwTB(4,4,mxDOUBLE_CLASS);  
  66.     mwArray mwTC(4,4,mxDOUBLE_CLASS);  
  67.   
  68.     mwTA.SetData(*ta, 4);  
  69.     mwTB.SetData(*tb, 4);  
  70.   
  71.     add(1, mwTC, mwTA, mwTB);  
  72.   
  73.     cout<<"tc = "<<endl;  
  74.     for(int i = 0; i < 1; i++)  
  75.     {  
  76.         for(int j = 0; j < 4; j++)  
  77.         {  
  78.             tc[i][j] = mwTC.Get(2,j+1,i+1);  
  79.   
  80.             cout<<"  "<<tc[i][j];  
  81.         }  
  82.         cout<<endl;  
  83.     }  
  84.   
  85. }  

结果即为两者相加的和。

以上程序中函数说明:

(1) 第7行初始化lib的代码貌似是必须的,否则我这里运行出错;而第44行和第45行的终止调用,

貌似注释掉也没有什么影响。
(2) mwArray对象有多种初始化方式,这里第13-15行表示初始化成1x1的int32类型对象,

第25-27行表示初始化成2x2的double类型对象。
(3) SetData函数第一个参数是一个mwArray型的一级指针,第二个参数表示元素个数。由于a,b

是一个int型的变量,故第16-17行对a,b做取地址运算;而da和db由于是二维数组名,即二级指针

常量,故第28-29行对da,db做了一级指针引用。
(4) Get函数也有多种调用形式。第19行调用中,Get函数第一个参数1,表示只用1个下标来访问

(类似于MATLAB中可以把一个矩阵看作是一个向量,以列为先序),第二个参数1表示访问第1

个元素;而第37行调用中,Get函数第一个参数2,表示用2个下标来访问(i是行索引,j是列索引

,又由于是以列为先序,所以j在前,i在后),同时由于MATLAB中下标是从1开始,而C++中下

标是从0开始,故做了j+1和i+1操作。


并且通过调用一些其他函数,调用matlab中的画图操作。测试代码如下:

[cpp] view plain copy
print?
  1. #include "stdafx.h"  
  2. #include <iostream>  
  3. #include <stdio.h>  
  4. #include "libAdd.h"  
  5. #include "showimage.h"  
  6. #include "engine.h"  
  7.   
  8. #include <stdlib.h>  
  9. #include <string.h>  
  10. #include "matrix.h"  
  11.   
  12.   
  13. using namespace std;  
  14.   
  15. #define BUFSIZE 256  
  16.   
  17. int _tmain(int argc, _TCHAR* argv[])  
  18. {  
  19.     //mclTerminateApplication();  
  20.     //一定要有这个才能使用<span style="font-family: Arial, Helvetica, sans-serif;">mxCreateDoubleMatrix分配空间</span>  
  21.     mclInitializeApplication(NULL,0);  
  22.   
  23.   
  24.     Engine *ep;  
  25.     mxArray *T = NULL, *result = NULL;  
  26.       
  27.     char buffer[BUFSIZE+1];  
  28.     double time[10] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 };  
  29.   
  30.   
  31.     if (!(ep = engOpen("\0"))) {  
  32.         fprintf(stderr, "\nCan't start MATLAB engine\n");  
  33.         return EXIT_FAILURE;  
  34.     }  
  35.   
  36.   
  37.     T = mxCreateDoubleMatrix(1, 10, mxREAL);  
  38.   
  39.     memcpy((void *)mxGetPr(T), (void *)time, sizeof(time));  
  40.   
  41.     engPutVariable(ep, "T", T);  
  42.   
  43.   
  44.     engEvalString(ep, "D = .5.*(-9.8).*T.^2;");  
  45.   
  46.   
  47.     engEvalString(ep, "plot(T,D);");  
  48.     engEvalString(ep, "title('Position vs. Time for a falling object');");  
  49.     engEvalString(ep, "xlabel('Time (seconds)');");  
  50.     engEvalString(ep, "ylabel('Position (meters)');");  
  51.   
  52.   
  53.     printf("Hit return to continue\n\n");  
  54.     fgetc(stdin);  
  55.   
  56.     printf("Done for Part I.\n");  
  57.     mxDestroyArray(T);  
  58.     engEvalString(ep, "close;");  
  59.   
  60.   
  61.   
  62.   
  63.   
  64.     buffer[BUFSIZE] = '\0';  
  65.     engOutputBuffer(ep, buffer, BUFSIZE);  
  66.     while (result == NULL) {  
  67.         char str[BUFSIZE+1];  
  68.   
  69.         printf("Enter a MATLAB command to evaluate. This command should\n");  
  70.         printf("create a variable X. This program will then determine\n");  
  71.         printf("what kind of variable you created.\n");  
  72.         printf("For example: X = 1:5\n");  
  73.         printf(">> ");  
  74.   
  75.         fgets(str, BUFSIZE, stdin);  
  76.   
  77.   
  78.         engEvalString(ep, str);  
  79.   
  80.   
  81.         printf("%s", buffer+2);  
  82.   
  83.   
  84.         printf("\nRetrieving X...\n");  
  85.         if ((result = engGetVariable(ep,"X")) == NULL)  
  86.             printf("Oops! You didn't create a variable X.\n\n");  
  87.         else {  
  88.             printf("X is class %s\t\n", mxGetClassName(result));  
  89.         }  
  90.     }  
  91.   
  92.   
  93.     printf("Done!\n");  
  94.     mxDestroyArray(result);  
  95.     engClose(ep);  
  96.   
  97.     return EXIT_SUCCESS;  
  98. }  

以上程序运行结果为:



画一朵花程序:

[cpp] view plain copy
print?
  1. #include "stdafx.h"  
  2. #include <iostream>  
  3. #include <stdio.h>  
  4. #include "libAdd.h"  
  5. #include "showimage.h"  
  6. #include "engine.h"  
  7.   
  8. #include <stdlib.h>  
  9. #include <string.h>  
  10. #include "matrix.h"  
  11. #include "showia.h"  
  12.   
  13. using namespace std;  
  14.   
  15.   
  16. #define BUFSIZE 256  
  17.   
  18. int _tmain(int argc, _TCHAR* argv[])  
  19. {  
  20.   
  21.     //mclTerminateApplication();  
  22.     //一定要有这个才能赋值  
  23.     mclInitializeApplication(NULL,0);  
  24.     Engine *ep;  
  25.   
  26.       
  27.     if (!(ep = engOpen("\0"))) {  
  28.         fprintf(stderr, "\nCan't start MATLAB engine\n");  
  29.         return EXIT_FAILURE;  
  30.     }  
  31.   
  32.     engEvalString(ep, "x=-8:0.5:8;");  
  33.     engEvalString(ep, "y=x;");  
  34.     engEvalString(ep, "[Y,X]=meshgrid(y,x);");  
  35.     engEvalString(ep, "R=sqrt(X.^2+Y.^2)+eps;");  
  36.     engEvalString(ep, "Z=2*sin(R)./R;");  
  37.     engEvalString(ep, "surf(X,Y,Z);");  
  38. }  


参考链接:

http://blog.sina.com.cn/s/blog_78ee50ce0102voy8.html


http://blog.sina.com.cn/s/blog_4cac891f0100ui0x.html


0 0
原创粉丝点击