在C中调用Matlab 在用C写程序时,有时会遇到数值计算问题,如矩阵的计算、优化问题、解微分方程等等。这些数值计算问题如果自己来实现的话,一来太费时间,二来自己的实现方案效率未必高。所以遇到这些数值计算问题时可以先上网搜一下,看看有没有现成的模块(当然要可靠)。另一种解决方法就是依靠matlab了。用过matlab 的人都知道,它提供了丰富的数值计算函数。在C程序中调用matlab函数即可轻松解决问题。 在进行联合编程前需要经行配置 1 Visual Studio的配置(VS2008为例) 选择"工具"→"选项"→"VC++目录",如下图所示添加路径 2matlab的配置 在matlab命令行输入mex -setup,按提示选择合适的选项 在matlab命令行输入mbuild -setup,按提示选择合适的选项 以上配置只需进行一次就可以了,不必每写一个程序都重复一遍。 在C中调用matlab有两种方法:1 在C程序中调用matlab引擎 2 matlab函数编译生成dll文件供C程序使用。以下分别介绍 1在C程序中调用matlab引擎 为了调用matlab引擎,首先需要引入相应的头文件 #include "engine.h" 然后需要加如下几行代码,这样顺利地完成连接。 #pragma comment( lib, "libeng.lib" ) #pragma comment( lib, "libmx.lib" ) #pragma comment( lib, "libmat.lib" ) 有时候你可程序所调用的函数可能还需要其他的库。如果有链接错误提示的话,上网搜一下,然后按上述格式把需要的库加上就可以了。 接下来就可以在需要的地方调用matlab引擎了。使用时首先需要打开引擎: Engine *ep; if (!(ep = engOpen("\0"))) { fprintf(stderr, "\nCan't start MATLAB engine\n"); return EXIT_FAILURE; } 接下来将C程序中相关的变量变为matlab需要的格式,一般使用mxCreateDoubleMatrix 和 memcpy函数。 完成转换后使用engPutVariable将数据送到matlab引擎。 最后调用engEvalString,将matlab命令作为其参数,就可以利用matlab引擎进行计算了。 计算完成后不要忘了清理工作: 使用mxDestroyArray清除mxCreateDoubleMatrix产生的变量,最后使用engClose关闭引擎。 下面是一个例子,绘制y=sin(t)的图像 代码: #include <stdlib.h> #include <stdio.h> #include <string.h> #include "engine.h" #pragma comment( lib, "libeng.lib" ) #pragma comment( lib, "libmx.lib" ) #pragma comment( lib, "libmat.lib" ) int main() { Engine *ep; if (!(ep = engOpen("\0"))) { fprintf(stderr, "\nCan't start MATLAB engine\n"); return EXIT_FAILURE; } int Nsample = 50; const double PI = 3.1415926; double *t = new double[Nsample] ; for(int i = 0; i < Nsample; i++) { t = i * 2 * PI / Nsample; } mxArray *T = NULL, *result = NULL; T = mxCreateDoubleMatrix(1, Nsample, mxREAL); memcpy((void *)mxGetPr(T), (void *)t, Nsample*sizeof(t[0])); engPutVariable(ep, "T", T); engEvalString(ep, "Y=sin(T);"); engEvalString(ep, "plot(T,Y);"); engEvalString(ep, "title('y=sin(t)');"); engEvalString(ep, "xlabel('t');"); engEvalString(ep, "ylabel('y');"); printf("Hit return to continue\n\n"); fgetc(stdin); mxDestroyArray(T); engEvalString(ep, "close;"); engClose(ep); return EXIT_SUCCESS; } 执行结果 2 C程序调用matlab生成的dll 如果需要matlab完成的功能比较通用,如果用上述方法,则会产生大量的重复代码。这里要讲的方法将对matlab 的调用做成一个模块,这样每次使用时只需调用这个模块就可以了。 首先将需要matlab完成的功能做成一个matlab函数,然后利用mcc命令编译,得到h、dll、lib等文件,在C工程中只需加入上述文件即可。下面是一个例子。 在做通信仿真时通常是给地一组信噪比,然后通过仿真得到在每个信噪比下的误码率,最后绘制出误码率对信噪比的曲线。 以前的做法是用C仿真,并将结果存在txt文件中,最后让matlab从txt文件中读取数据并绘图。 利用这里的方法,可以写一个matlab绘图的模块,并在C程序的最后调用,这样就能自动完成绘图了。 Matlab代码 function showBER(SNR_indB,BER) semilogy(SNR_indB,BER,'-o','linewidth',2); grid on xlabel('E_b/N_0(dB)'); ylabel('BER'); 在matlab命令行中输入 mcc -B csharedlib:showBER showBER.m 得到一组文件 将其中的.dll .h .lib文件拷贝到C工程中。 在需要调用绘图模块的cpp文件中加入如下代码 #include "showBER.h" #pragma comment( lib, "libeng.lib" ) #pragma comment( lib, "libmx.lib" ) #pragma comment( lib, "libmat.lib" ) #pragma comment( lib, "mclmcrrt.lib" ) #pragma comment( lib, "showBER.lib" ) 下面的一段代码显示了调用绘图模块的方法: double SNR[] = {0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5}; double BER[] = {9.728816e-002, 8.099609e-002, 5.633803e-002, 3.733608e-002, 1.253970e-002, 3.936489e-003, 1.206820e-003, 2.104052e-004, 3.109879e-005, 3.365857e-006, 2.565067e-007}; int len = sizeof(SNR) / sizeof(SNR[0]); showBERInitialize(); mxArray* xSNR = mxCreateDoubleMatrix(1, len, mxREAL); memcpy(mxGetPr(xSNR), (void*)SNR, sizeof(SNR)); mxArray* xBER = mxCreateDoubleMatrix(1, len, mxREAL); memcpy(mxGetPr(xBER), (void*)BER, sizeof(BER)); mlfShowBER(xSNR,xBER); system("PAUSE"); showBERTerminate(); 1在调用绘图模块之前需要调用showBERInitialize 2在调用绘图模块之后需要调用showBERTerminate 3使用mxCreateDoubleMatrix 和 memcpy 函数将C程序中的变量送入matlab中 4通过mlfShowBER调用matlab模块。而mlf***函数的调用格式需要参考***.h(此例为showBER.h)文件中的声明。 运行结果为 |
欢迎光临 52matlab技术网站,matlab教程,matlab安装教程,matlab下载 (http://www.52matlab.com/) | Powered by Discuz! X3.2 |