转自:https://www.cnblogs.com/xpvincent/archive/2013/02/05/2893046.html

本文主要介绍VC与Matlab混合编程的两种方法,并详细介绍了VC向Matlab传递复杂数据:结构体的方法,有详细代码说明。

Matlab 主要面对科学计算、可视化以及交互式程序设计的高科技计算环境,但由于Matlab开发平台上开发的程序不能脱离Matlab运行环境,因而在处理一些实际应用问题时显得灵活性不足,而VC++则在一定程度上能够弥补这一漏洞,因此,将二者结合共用,各献其长,可以为科研工作和工程开发提供更为强大的技术支持。

Matlab作为控制系统设计的一种通用工具,它可以很方便的和VC进行连接。一般而言,Matlab与VC混合编程的实现方法有很多种,这里主要介绍以下两种:

1.  VC调用Matlab Engine的方式:

Matlab Engine是一组Matlab提供的接口函数,支持C/C++语言,Matlab Engine采用C/S(客户机/服务器)模式,Matlab作为后台服务器,而C/C++程序作为前台客户机,向Matlab Engine传递执行命令和数据信息,从Matlab Engine接收执行结果。用户可以在前台应用程序中调用这些接口函数,实现对Matlab Engine的控制。采用这种方法几乎能利用Matlab全部功能,但是需要在机器上安装Matlab软件,缺点是执行效率较低。下面简单介绍下这种方式的实现步骤:

1.1 API接口介绍

先来介绍一组Matlab提供的引擎API接口:(仅作简单功能介绍,详细参数说明请参考Matlab帮助)

Engine* engOpen(const char* startcmd)启动Matlab引擎

int engClose(Engine* ep) 关闭Matlab引擎

int engEvalString(Engine* ep, const char* string)执行Matlab表达式

mxArray* engGetArray(Engine* ep, const char* name)获取一个变量数组的值

int engPutArray(engine* ep, const mxArray* mp)设置一个变量数组的值

int engPutVariable(Engine *ep, const char *name, const mxArray *pm)同上

mxArray *engGetVariable(Engine *ep, const char *name)获取一个变量

int engOutputBuffer(Engine* eP,char* p,int n)获取输出字符串

1.2   VC环境配置

要想在VC集成环境下调用Matlab引擎实现VC和Matlab的混合编程,一般需要经过以下几个必要的步骤:(以下以Matlab2008a和VS2005版本为例)

(1)添加include路径:将“\extern\include”(在Matlab的安装路径下)路劲添加到VC编译器的include下

(2)添加lib路径:将“\extern \lib\win32\microsoft” (在Matlab的安装路径下) 路径添加到VC编译器的lib下

(3)加载lib:需要加载至少libmx.lib、libmat.lib、libeng.lib三个库

(4)include头文件:在要使用 engine 函数的地方包含engine.h头文件

(5)设置系统环境变量:环境变量加上.\Program Files\MATLAB\R2010b\bin\win64 否则编译成功运行时会显示缺少dll

(6)VC工程build位宽版本跟matlab版本一致:如果matlab版本是32位,那么VC工程也要win32的build;如果matlab版本是64未,那么VC工程也要x64的build

(7)如果engOpen()函数返回空指针:手动注册matlab,在DOS窗口输入如下命令 

cd matla路径\bin\win32  matlab /regserver 

或者 

cd matlab路径\bin\win64  matlab /regserver

Note:使用管理员身份运行cmd.exe

1.3   引擎调用

接下来就可以在VC中调用Matlab引擎了,简单的示例代码如下:

#include "engine.h"#pragma comment(lib, "libeng.lib")
#pragma comment(lib, "libmx.lib")
#pragma comment(lib, "libmat.lib")void TestDeno()
{Engine* pEng = NULL;if (!(pEng = engOpen(NULL))){printf("Open matlab enging fail!");return;}//call Engine plot A*sin(t)+B A=2 B=1
mxArray *A = NULL;double init = 2;A = mxCreateDoubleMatrix(1, 1, mxREAL);memcpy((void*) mxGetPr(A), (void*)&init, sizeof (double));engPutVariable(pEng, "A", A);init = 1;memcpy((void*) mxGetPr(A), (void*)&init, sizeof (double));engPutVariable(pEng, "B", A);mxDestroyArray(A);Sleep(3*60*1000);engEvalString(pEng, "t=0:0.2:7;plot(t,A*sin(t)+B);");if(NULL != pEng){engClose(pEng);}
}

示例代码通过VC调用Matlab引擎,绘制正弦曲线,相对简单,就不再详细解释,效图如下:

2. VC调用Matlab DLL的方式

DLL是一个可执行的二进制文件。把很多通用的功能放在DLL中,可以供各种应用程序调用,这样可以很好的减少外部存储空间的占有量,并实现代码的共享。Matlab也支持将m程序编译成dll,供其他语言(包括VC、VB、Fortran等)调用,下面先简单介绍下Matlab DLL的编译步骤:

2.1  Matlab DLL制作

(1)配置Matlab的编译器跟,要将mex和mbuil两个都配置成本机上安装的VC,mbuild的配置方法同mex

(2)编译m函数成为dll,在matlab命令空间中使用mcc命令编译m文件:(mcc的使用参考Matlab帮助)

示例:将一个Matlab函数MyFun 编译成libMyFun 的命令:

mcc –W cpplib:libMyFun –T link:lib MyFun

参数说明:-W控制编译之后的封装格式,cpplib表示c++的lib,冒号之后是编译输出lib名,-T表示目标,link:lib表示连接到lib的目标,MyFun是待编译的m文件名,编译成功之后,会输出三个文件:libMyFun.lib libMyFun.dll libMyFun.h

2.2 DLL在VC中调用

要想在VC集成环境下调用Matlab的DLL,实现VC和Matlab的混合编程,一般需要经过以下几个必要的步骤:(以下以Matlab2008a和VS2005版本为例)

(1)VC环境配置,同前面VC调用Matlab引擎方式类似,也需要配置VC的编译环境,其中include路径、lib路径和前一种方式相同,加载的lib变更为:mclmcrrt.lib、libmx.lib、libmat.lib、mclmcr.lib四个,include的头文件变更为:mclmcr.h、matrix.h、mclcppclass.h三个。

(2)DLL中函数的调用,先看一下m函数编译成C++Dll之后的函数声明,例:matlab函数:function [y, out] = CaculateFun(x, in)编译之后对应c++的声明:void MW_CALL_CONVCaculateFun(int nargout, mwArray& y, mwArray& out, const mwArray& x, const mwArray& in)参数int nargout指定调用时,输出参数的个数,紧跟的后续nargout个参数y、out为输出参数,后续再剩下的多个参数x、in就为输入参数。

(3)注意事项:在VC中调用dll中的函数之前,需要先调用函数libFunInitialize初始化,在调用完函数以后,需要再调用函数libFunTerminate和mclTerminateApplication终止。

准备好了上述步骤,就可以在VC中调用DLL中函数的了,简单的示例代码如下:

// include matlab sys head file
#include "mclmcr.h"
#include "matrix.h"
#include "mclcppclass.h"// include lib head file
#include "libCaculateFun.h"// link matlab sys lib
#pragma comment(lib, "mclmcrrt.lib")
#pragma comment(lib, "libmx.lib")
#pragma comment(lib, "libmat.lib")
#pragma comment(lib, "mclmcr.lib")// link lib
#pragma comment(lib, "libCaculateFun.lib")void TestDeno()
{// init libif (!(libCaculateFunInitialize())){std::cout<<"Could not init lib !"<<endl;return -1;}double xxxx[2] = {0};double inin    = 0;double yyyy[2] = {0};double outo    = 0;// 为函数参数分配内存空间mwArray mwXX(1, 2, mxDOUBLE_CLASS);mwArray mwIn(1, 1, mxDOUBLE_CLASS);mwArray mwYY(1, 2, mxDOUBLE_CLASS);mwArray mwOut(1, 2, mxDOUBLE_CLASS);// 为输入参数赋值mwXX.SetData(&xxxx, 2);mwIn.SetData(&inin, 1);// 调用计算函数CaculateFun(2, mwYY, mwOut, mwXX, mwIn);// 获取输出参数outo = mwOut.Get(1, 1);// lib Terminate
    libCaculateFunTerminate();// MCR Terminate
    mclTerminateApplication();
}

示例代码通过VC调用Matlab DLL,将变量xxxx的值付给yyyy,将变量inin的值付给outo,相对简单,就不再详细解释。

3.  VC向Matlab函数传递参数

前面在介绍两种混合编程的方式时,示例代码中已经涉及到了参数的传递问题,对于VC中的简单数据类型:变量、数组等,网上已经有很多资料介绍,前面示例代码中也有所体现,这里不再详细说明。

关于复杂数据结构:用户自定义结构体类型,处理起来比较麻烦,网上能找到的资料也较少,由于前面提及的两种方式,在传递参数时,使用的数据类型是不一致的:引擎方式只能是mxArray类型,而DLL方式的参数只能是mwArray,因此需要分别介绍将结构体转换成这两种类型的方法:

先来定义两个结构体:

// 三维坐标系中的点
struct Postion
{double x;double y;double z;
};// 名字标示的一个坐标点
struct Coordinate
{struct Postion pos;char name[ARRAYSIZE];
};

分别介绍将如上两个结构体转成Matlab能使识别的Array的方法

(1)结构体转换成mxArray:解释比较多余,就直接上代码吧:

mxArray *Staruct2mxArray(struct Postion *pStaruct)
{mxArray *pm, *mx;mwSize m = 1, n = 1;const int nfields = 3;const char *fieldnames[3] = {"x","y","z"};const mwIndex index = 0;pm = mxCreateStructMatrix(m, n, nfields, fieldnames);mx = mxCreateNumericMatrix(m, n, mxDOUBLE_CLASS, mxREAL);memcpy(mxGetPr(mx), &(pStaruct->x), sizeof(double));mxSetFieldByNumber(pm, index, 0, mx);mx = mxCreateNumericMatrix(m, n, mxDOUBLE_CLASS, mxREAL);memcpy(mxGetPr(mx), &(pStaruct->y), sizeof(double));mxSetFieldByNumber(pm, index, 1, mx);mx = mxCreateNumericMatrix(m, n, mxDOUBLE_CLASS, mxREAL);memcpy(mxGetPr(mx), &(pStaruct->z), sizeof(double));mxSetFieldByNumber(pm, index, 2, mx);return pm;
}mxArray *Staruct2mxArray(struct Coordinate *pStaruct)
{mxArray *pm, *mx;mwSize m = 1, n = 1;const int nfields = 2;const char *fieldnames[2] = {"pos","name"};const mwIndex index = 0;pm = mxCreateStructMatrix(m, n, nfields, fieldnames);mx = Staruct2mxArray(&(pStaruct->pos));mxSetFieldByNumber(pm, index, 0, mx);n = ARRAYSIZE;mx = mxCreateNumericMatrix(m, n, mxCHAR_CLASS, mxREAL);memcpy(mxGetPr(mx), pStaruct->name, sizeof(char)*ARRAYSIZE);mxSetFieldByNumber(pm, index, 1, mx);return pm;
}

(2)结构体转换成mwArray:

mwArray Staruct2mwArray(struct Postion *pStaruct)
{mwSize m = 1, n = 1;const int nfields = 3;const char *fieldnames[3] = {"x","y","z"};mwArray pm(m, n, nfields, fieldnames);mwArray mx(pStaruct->x);pm(fieldnames[0], 1, 1) = mx;mwArray my(pStaruct->y);pm(fieldnames[1], 1, 1) = my;mwArray mz(pStaruct->z);pm(fieldnames[2], 1, 1) = mz;return pm;
}mwArray Staruct2mwArray(struct Coordinate *pStaruct)
{mwSize m = 1, n = 1;const int nfields = 2;const char *fieldnames[2] = {"pos","name"};const mwIndex index = 0;mxArray pm(m, n, nfields, fieldnames);mxArray mpos = Staruct2mwArray(&(pStaruct->pos));pm(fieldnames[0], 1, 1) = mpos;mxArray mname(pStaruct->name);pm(fieldnames[1], 1, 1) = mname;return pm;
}

(3)mxArray转换成结构体:

struct Coordinate *mwArray2Staruct(mwArray pm)
{// 代码仅处理 name 字段 pos 字段是三个简单类型省略struct Coordinate *pStaruct = new struct Coordinate;const int nfields = 2;const char *fieldnames[2] = {"pos","name"};mwArray mwStr = pm.Get(fieldnames[1], 1, 1);char *str = strdup(mwStr.ToString());memcpy(pStaruct->name,str,sizeof(char)*ARRAYSIZE);return pStaruct;
}

(4)mwArray转换成结构体:

struct Coordinate *mxArray2Staruct(mxArray *pm)
{// 代码仅处理 name 字段 pos 字段是三个简单类型省略struct Coordinate *pStaruct = new struct Coordinate;mxArray * mxname = mxGetFieldByNumber(pm, 1, 1)mxArray * str = mxGetPr(mxname);memcpy(pStaruct->name,str,sizeof(char)*ARRAYSIZE);return pStaruct;
}

VC与matlab混合编程相关推荐

  1. VC与Matlab混合编程的快速实现(3-1)

    [原创]VC与Matlab混合编程的快速实现(3-1) 发信站: BBS 水木清华站 (Mon May 19 21:30:19 2003), 转信 3       在VC++中使用Matlab生成的动 ...

  2. matlab的矩阵编译器,MATLAB引擎方式实现VC与MATLAB混合编程

    VS2008是当前主流的应用程序开发环境之一,开发环境强大,开发的程序执行速度快.但在科学计算方面函数库显得不够丰富.读取.显示数据图形不方便.Matlab是一款将数值分析.矩阵计算.信号处理和图形显 ...

  3. matlab与vc混合编程指导书.doc,vc与matlab混合编程—基于com.doc

    vc与matlab混合编程-基于com.doc VC与MATLAB混合编程基于COM2010年03月21日星期日1118注意旨在提供一份VC调用MATLAB的快速试验参考和一些实际经验,不保证所有内容 ...

  4. VC与Matlab混合编程之基于MATLAB RTW 的建模仿真

        本文章只是博主用来记录自己的学习过程以及期间遇到的一些问题及解决方案的总结         首先Matlab(Matlab7.0)仿真模型部分配置过程如下: 注:上面的图是在Matlab201 ...

  5. c 使用matlab引擎,[转载]C与MATLAB混合编程之调用MATLAB引擎

    Visual Studio调用MATLAB需要的配置已经在<Visual Studio调用MATLAB的配置>一文中给出了详细的步骤,本文将介绍混合编程的示例. 在C中调用MATLAB,据 ...

  6. c 与matlab混编,C与MATLAB混合编程之调用MATLAB引擎

    Visual Studio调用MATLAB需要的配置已经在<Visual Studio调用MATLAB的配置>一文中给出了详细的步骤,本文将介绍混合编程的示例. 在C中调用MATLAB,据 ...

  7. matlab两个多项式相除,C++和MATLAB混合编程求解多项式系数(矩阵相除)

    摘要:MATLAB对于矩阵处理是非常高效的,而C++对于矩阵操作是非常麻烦的,因而可以采用C++与MATLAB混合编程求解矩阵问题. 主要思路就是,在MATLAB中编写函数脚本并使用C++编译为dll ...

  8. matlab求解多项式系数,C++和MATLAB混合编程求解多项式系数(矩阵相除)

    摘要:MATLAB对于矩阵处理是非常高效的,而C++对于矩阵操作是非常麻烦的,因而可以采用C++与MATLAB混合编程求解矩阵问题. 主要思路就是,在MATLAB中编写函数脚本并使用C++编译为dll ...

  9. 怎样用matlab打开mw文,C# matlab混合编程 MWArray使用笔记

    C# matlab混合编程 徐凯Email:xukai19871105@http://www.doczj.com/doc/1a6e191fff00bed5b9f31dbf.html 这几天突然想搞一搞 ...

  10. vc与matlab联合,浅析VC与Matlab联合编程(二) - VC知识库文章

    浅析VC与Matlab联合编程(二) 作者:邓科 下载源代码 在"浅析VC与Matlab联合编程 (一)"中简单介绍了VC与matcom的接口编程,实现了VC调用matcom的一个 ...

最新文章

  1. php对分数排序,php-MySQL @grouping结果按ID并按分数排序”问题
  2. [蓝桥杯][2017年第八届真题]k倍区间(数学+思维)
  3. Python动态导入模块、类
  4. :Android网络编程--XML之解析方式:SAX
  5. 仓库镜像源为清华_conda国内镜像修改(最新版)
  6. M1芯片电脑SVN安装
  7. STM32第一个demo与软件设置
  8. Matlab使用EMD
  9. word页面顺序倒过来_WORD2010双面打印出来的是倒过来的,不是按顺序的怎么设置...
  10. dataGridView单元格引用
  11. 服务器维护 灵魂兽,魔兽世界7.0新灵魂兽麋鹿捕捉方法
  12. Android 网络小说阅读APP实现详解
  13. [EI检索]2022智能制造、先进传感与大数据国际会议诚邀您关注
  14. 数据库索引的作用?什么时候用索引?优缺点?
  15. linux查看当前运行的进程
  16. CentOS安装JDK1.8
  17. 扫地机器人划伤地板_使用扫地机器人地板会被破坏吗
  18. Java8新特性 - 04 - 方法引用05 - 方式四 【类名::new】
  19. 达内学python_通过在达内学习python我的职场之路更加宽广了
  20. 4个鲜为人知的Git命令

热门文章

  1. 6.2 数据通路的建立
  2. windows10系统下vue开发环境搭建
  3. NUCLEO开发板:STM32 st-link驱动程序错误
  4. 解决微信二次分享失败
  5. Keil 中 Error L6002U
  6. Python语言程序设计(嵩天老师版)第二周代码解析
  7. 统计学第八版贾俊平课后答案
  8. 【数据结构排序算法(五)】二路归并排序
  9. Javaweb实现在线预览word文件
  10. 嵌入式linux应用开发之常用shell脚本总结