VS2013调用MATLAB内建函数

来源:互联网 发布:网络直播对大学生影响 编辑:程序博客网 时间:2024/05/15 23:52

       在用C写程序时,有时会遇到数值计算问题,如矩阵的计算、优化问题、解微分方程等等。这些数值计算问题如果自己来实现的话,一来太费时间,二来自己的实现方案效率未必高。所以遇到这些数值计算问题时可以先上网搜一下,看看有没有现成的模块(当然要可靠)。另一种解决方法就是依靠matlab了。用过matlab 的人都知道,它提供了丰富的数值计算函数。在C程序中调用matlab函数即可轻松解决问题。


环境:

win7x64

MATLAB R2013a x64

Visual Studio 2013


步骤:

1.配置VS2013属性表 项目属性 - 配置属性 - VC++目录 -

    包含目录:D:\Install\MatLab\extern\include;

    库目录:D:\Install\MatLab\extern\lib\win64\microsoft;

       项目属性 - 配置属性 -链接器 - 输入 - 附加依赖项:libmx.lib;libmat.lib;libeng.lib;

2.matlab的配置

    配置环境变量(很重要,否则编译会出现“找不到libmx.dll文件”):D:\Install\MatLab\bin\win64;

       在matlab命令行输入mex -setup,按提示选择合适的选项

       在matlab命令行输入mbuild -setup,按提示选择合适的选项

       以上配置只需进行一次就可以了,不必每写一个程序都重复一遍。

 

在C中调用matlab有两种方法:

1.在C程序中调用matlab引擎

为了调用matlab引擎,首先需要引入相应的头文件

#include "engine.h"

然后需要加如下几行代码,这样顺利地完成连接。

#pragma comment( lib, "libeng.lib" )#pragma comment( lib, "libmx.lib" )#pragma comment( lib, "libmat.lib" )

       有时候你可程序所调用的函数可能还需要其他的库。如果有链接错误提示的话,上网搜一下,然后按上述格式把需要的库加上就可以了。

接下来就可以在需要的地方调用matlab引擎了。

       使用时首先需要打开引擎:

<pre name="code" class="cpp">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] = 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 onxlabel('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)文件中的声明。

1 0
原创粉丝点击