52matlab技术网站,matlab教程,matlab安装教程,matlab下载

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 8766|回复: 0
打印 上一主题 下一主题

在C中调用Matlab

[复制链接]

6

主题

8

帖子

63

积分

版主

Rank: 7Rank: 7Rank: 7

积分
63
跳转到指定楼层
楼主
发表于 2015-3-14 20:58:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 yangshangbin 于 2015-3-14 21:01 编辑



                                                                                                                          在C中调用Matlab                                                                                                                                                                                                                                                              

                                         


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

运行结果为










回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|52matlab技术网站 ( 粤ICP备14005920号-5 )

GMT+8, 2024-11-29 12:51 , Processed in 0.068084 second(s), 18 queries .

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表