C调用MATLAB函数

来源:互联网 发布:淘宝店长工资多少 编辑:程序博客网 时间:2024/05/16 12:16

在用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;

constdouble PI = 3.1415926;

double*t = newdouble[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代码

functionshowBER(SNR_indB,BER)

semilogy(SNR_indB,BER,'-o','linewidth',2);

gridon

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)文件中的声明。

 

运行结果为

原创粉丝点击