C++ 与 MATLAB 混合编程总结(14)
1. 前言
因为毕业设计的需求,研究了一下,C++如何与MATLAB一起混合编程,中间走了一些弯路,这里总结一下。
我用的主要是C++如何调用MATLAB,而没有涉及MATLAB如何调用C++。
注意:根据摸索的经验,比较兼容的组合是:「Microsoft Visual Stuido Enterprise 2015 + Matlab R2015b win 32位」。其它版本的组合可能会出现这问题,那问题,你也可以自己摸索一下。用32位MATLAB的原因:VS的工程一般都是32位调试,而32位MATLAB封装成的「dll」文件是32位的,放到VS里边,都是32位,正好运行。而64位MATLAB封装的「dll」文件是64位,如果VS工程是32位,则会提示出错。
Microsoft Visual Stuido Enterprise 2015
>> Microsoft Visual Stuido Enterprise 2015
>> 密钥
Matlab R2015b win 32位
>> R2015b_win32.iso
>> crack.7z
>> MATLAB_R2015b安装+破解教程.pdf
C++调用MATLAB,主要有两种方式:(1)调用MATLAB生成的「dll」文件,对MATLAB没有那么强的依赖,可以脱离MATLAB独立运行。(2)C++调用MATLAB引擎,这个必须要有MATLAB。本质是通过C++把MATLAB命令字符串送到MATLAB的「command windows」里边,然后MATLAB运行该命令。
“方式(1)”的使用场景举例:MATLAB里边有很多封装好的函数,可能有些自己用C++不会写,这时候可以把这些函数封装成「dll」文件,放到C++里边调用。
“方式(2)”的使用场景举例:C++跑出了数据,直接调用MATLAB绘图,查看图形结果,不用把数据再导到MATLAB中画图。
2. 学会使用“方式(1)”,参考以下资料即可:
资料1:https://www.cnblogs.com/yangang92/p/5312991.html
资料2:https://www.cnblogs.com/AlgrithmsRookie/p/7049467.html
资料3:https://blog.csdn.net/hong__fang/article/details/43307701
资料4:https://blog.csdn.net/cuiguanjun/article/details/52828192
资料5:http://blog.sina.com.cn/s/blog_b3facf740101e3c7.html
因为这个方法涉及到「dll」文件,不方便在这里放例子。看完上述资料,手动操作一下,应该懂得差不多了。应该懂得如何封装成"dll“文件,并知道如何在C++里边写接口函数,调用「dll」文件了。
3. 学会使用“方式(2)”,参考以下资料即可:
资料1:http://dev.yesky.com/300/2343300.shtml
资料2:https://www.cnblogs.com/Vonng/p/4232586.html
3.1 以下是一些我做毕业设计用到的代码,可以参考一下:
3.1.1 参考代码1:
C++读取MATLAB的.m文件,并发送到MATLAB运行。
代码用到的头文件自己记得添加,包括「string、vector」等,这里只是主体代码。别忘了最主要的「engine.h」,参看3.1.2。
//C++读取MATLAB的.m文件,并发送到MATLAB运行
//打开MATLAB引擎
Engine *matlabEngine; //定义MATLAB引擎指针
if (!(matlabEngine = engOpen(NULL))) //测试是否启动Matlab引擎成功
{
cout << "Can't start Matlab engine!" << endl;
exit(1);
}
//读取文件中有效命令到"matlabCode",并发送到MATLAB
ifstream fin;
fin.open("voronoiData.m", ios_base::in);
string matlabCode;
string buf;
string zhuShi = "%"; //** 用于查找是否有注释
string::size_type index;
while (getline(fin, buf))
{
if (buf.empty()) //跳过文件中的空行
{
fin.clear();
buf.erase(); //遇到空行,输入流被阻断,需要重置,以便后续读取
}
else //判断某行是否有注释,如果有,去掉注释内容
{
index = buf.find(zhuShi); //查找该行是否有注释,依据MATLAB注释关键字"%"定位
if (index == string::npos)
{
buf += ";";
matlabCode += buf;
buf.erase();
}
else
{
string temp(buf, 0, index); //去掉注释内容
buf.erase();
temp += ";";
matlabCode += temp;
}
}
}
engEvalString(matlabEngine, matlabCode.c_str()); //命令发送到MATLAB
fin.close(); //关闭文件
3.1.2 参考代码2:
用C++编写代码实现MATLAB的「plot、bar」函数。
Plot.h
#pragma once
#include<vector>
#include"engine.h"
#include"CSBS.h"
#include<string>
using std::string;
using std::vector;
/*-----------------------------------------MATLAB Plot函数-----------------------------------------*/
void Plot(vector<double>& x_vec, vector<double>& y_vec, string plotCommand, Engine* matlabEngine);
/*-----------------------------------------------------------------------------------------------------*/
/*----------------------------------------------画资源分配圈-----------------------------------------*/
void CircleCenterPoint(double x, double y, Engine* matlabEngine);
/*-----------------------------------------------------------------------------------------------------*/
/*-----------------------------------------画出组内CSBS的R_sa圈------------------------------------*/
void CircleCSBS(vector<CSBS>& GroupCSBS_vec, double R_sa, Engine* matlabEngine);
/*-----------------------------------------------------------------------------------------------------*/
/*-------------------------------------------关闭一个图形--------------------------------------------*/
void closeOnefigure(Engine* matlabEngine);
/*-----------------------------------------------------------------------------------------------------*/
/*-------------------------------------------关闭所有图形--------------------------------------------*/
void closeAllfigure(Engine* matlabEngine);
/*-----------------------------------------------------------------------------------------------------*/
/*-----------------------------------------MATLAB bar函数-----------------------------------------*/
void Bar(vector<vector<double> >& my_vec2, vector<vector<double> >& compared_vec2, Engine* matlabEngine);
/*-----------------------------------------------------------------------------------------------------*/
Plot.cpp
#include"Plot.h"
#include"GlobalVariable.h"
using std::string;
/*-----------------------------------------MATLAB Plot函数-----------------------------------------*/
void Plot(vector<double>& x_vec, vector<double>& y_vec, string plotCommand, Engine* matlabEngine)
{
//计算矩阵的列数
int rowNum = x_vec.size();
//计算当前编译环境一个double型数据占用几个字节
double temp = 100;
int byte = sizeof(temp);
//定义mxArray数组、赋值、写入MATLAB工作空间
mxArray *X = mxCreateDoubleMatrix(1, rowNum, mxREAL);
mxArray *Y = mxCreateDoubleMatrix(1, rowNum, mxREAL);
memcpy((void *)mxGetPr(X), (void*)(&x_vec.at(0)), rowNum * byte);
memcpy((void *)mxGetPr(Y), (void*)(&y_vec.at(0)), rowNum * byte);
engPutVariable(matlabEngine, "X", X);
engPutVariable(matlabEngine, "Y", Y);
//向MATLAB引擎发送绘图命令
engEvalString(matlabEngine, plotCommand.c_str());
//销毁mxArray数组
mxDestroyArray(X);
mxDestroyArray(Y);
}
/*-----------------------------------------------------------------------------------------------------*/
/*----------------------------------------------画资源分配圈-----------------------------------------*/
void CircleCenterPoint(double x, double y, Engine* matlabEngine)
{
//计算当前编译环境一个double型数据占用几个字节
double temp = 100;
int byte = sizeof(temp);
//定义mxArray数组、赋值、写入MATLAB工作空间
mxArray *X = mxCreateDoubleMatrix(1, 1, mxREAL);
mxArray *Y = mxCreateDoubleMatrix(1, 1, mxREAL);
memcpy((void *)mxGetPr(X), (void*)&x, 1 * byte);
memcpy((void *)mxGetPr(Y), (void*)&y, 1 * byte);
engPutVariable(matlabEngine, "X", X);
engPutVariable(matlabEngine, "Y", Y);
//资源分配圈画图坐标
vector<double> circleX_vec;
vector<double>circleY_vec;
for (double theta = 0.0; theta <= 2 * PI; theta = theta + PI / 1000.0)
{
double x = RS_RADIO*cos(theta);
double y = RS_RADIO*sin(theta);
circleX_vec.push_back(x);
circleY_vec.push_back(y);
}
int rowNum = circleX_vec.size();
//定义mxArray数组、赋值、写入MATLAB工作空间
mxArray *circleX = mxCreateDoubleMatrix(1, rowNum, mxREAL);
mxArray *circleY = mxCreateDoubleMatrix(1, rowNum, mxREAL);
memcpy((void *)mxGetPr(circleX), (void*)(&circleX_vec.at(0)), rowNum * byte);
memcpy((void *)mxGetPr(circleY), (void*)(&circleY_vec.at(0)), rowNum * byte);
engPutVariable(matlabEngine, "circleX", circleX);
engPutVariable(matlabEngine, "circleY", circleY);
//向MATLAB引擎发送绘图命令
engEvalString(matlabEngine, "plot(X,Y,'k^')");
engEvalString(matlabEngine, "plot(circleX,circleY,'k')");
//销毁mxArray数组
mxDestroyArray(X);
mxDestroyArray(Y);
mxDestroyArray(circleX);
mxDestroyArray(circleY);
}
/*-----------------------------------------------------------------------------------------------------*/
/*-----------------------------------------画出组内CSBS的R_sa圈------------------------------------*/
void CircleCSBS(vector<CSBS>& GroupCSBS_vec, double R_sa, Engine* matlabEngine)
{
//计算当前编译环境一个double型数据占用几个字节
double temp = 100;
int byte = sizeof(temp);
for (auto iCSBS = GroupCSBS_vec.begin(); iCSBS != GroupCSBS_vec.end(); iCSBS++)
{
//R_sa圈画图坐标
double x = iCSBS->GetPosition().GetX();
double y = iCSBS->GetPosition().GetY();
vector<double> circleX_vec;
vector<double>circleY_vec;
for (double theta = 0.0; theta <= 2 * PI; theta = theta + PI / 1000.0)
{
double x1 = x + R_sa * cos(theta);
double y1 =y + R_sa * sin(theta);
circleX_vec.push_back(x1);
circleY_vec.push_back(y1);
}
int rowNum = circleX_vec.size();
//定义mxArray数组、赋值、写入MATLAB工作空间
mxArray *circleX = mxCreateDoubleMatrix(1, rowNum, mxREAL);
mxArray *circleY = mxCreateDoubleMatrix(1, rowNum, mxREAL);
memcpy((void *)mxGetPr(circleX), (void*)(&circleX_vec.at(0)), rowNum * byte);
memcpy((void *)mxGetPr(circleY), (void*)(&circleY_vec.at(0)), rowNum * byte);
engPutVariable(matlabEngine, "circleX", circleX);
engPutVariable(matlabEngine, "circleY", circleY);
//向MATLAB引擎发送绘图命令
engEvalString(matlabEngine, "plot(circleX,circleY,'r-')");
//销毁mxArray数组
mxDestroyArray(circleX);
mxDestroyArray(circleY);
}
}
/*-----------------------------------------------------------------------------------------------------*/
/*-------------------------------------------关闭一个图形--------------------------------------------*/
void closeOnefigure(Engine* matlabEngine)
{
engEvalString(matlabEngine, "close");
}
/*-----------------------------------------------------------------------------------------------------*/
/*-------------------------------------------关闭所有图形--------------------------------------------*/
void closeAllfigure(Engine* matlabEngine)
{
engEvalString(matlabEngine, "close all");
}
/*-----------------------------------------------------------------------------------------------------*/
/*-----------------------------------------MATLAB bar函数-----------------------------------------*/
void Bar(vector<vector<double> >& my_vec2, vector<vector<double> >& compared_vec2, Engine* matlabEngine)
{
int lineNum = my_vec2.size();
int rowNum = my_vec2[0].size();
//计算当前编译环境一个double型数据占用几个字节
double temp = 100;
int byte = sizeof(temp);
//定义mxArray数组、赋值、
mxArray *X = mxCreateDoubleMatrix(lineNum, rowNum, mxREAL);
mxArray *Y = mxCreateDoubleMatrix(lineNum, rowNum, mxREAL);
//赋值;mxArray数据赋值顺序是一列一列来,而不是一行一行来
auto ptrX = mxGetPr(X); //获取指向X实部的指针(指向实部第一个元素)
auto ptrY = mxGetPr(Y); //获取指向Y实部的指针(指向实部第一个元素)
for (int j = 0; j < rowNum; j++)
{
for (int i = 0; i < lineNum; i++)
{
*ptrX = my_vec2[i][j];
*ptrY = compared_vec2[i][j];
ptrX++;
ptrY++;
}
}
//写入MATLAB工作空间
engPutVariable(matlabEngine, "X", X);
engPutVariable(matlabEngine, "Y", Y);
//向MATLAB引擎发送绘图命令
string plotCommand = "figure;y_label={'0%','10%','20%','30%','40%','50%','60%','70%','80%','90%','100%'};subplot(1,2,1);bar(X,'stack');title('my');set(gca, 'YTickLabel',y_label);subplot(1,2,2);bar(Y,'stack');title('compared');set(gca, 'YTickLabel',y_label);colormap(bone);legend('资源分配前的子信道','算法分配的子信道','资源分配后仍需要的子信道');";
engEvalString(matlabEngine, plotCommand.c_str());
}
/*-----------------------------------------------------------------------------------------------------*/
其中,「string plotCommand」就是MATLAB的绘图命令,比如如下调用「Plot」的方法:
Plot(X, SD_ReuseRB, "figure(3);hold on;box on;grid on;xlabel('number of CSBS');ylabel('SD');plot(X,Y,'r-o');", matlabEngine);
未完 ......
点击访问原文(进入后根据右侧标签,快速定位到本文)
C++ 与 MATLAB 混合编程总结(14)的更多相关文章
- C++和MATLAB混合编程-DLL
先小话一下DLL,DLL是动态链接库,是源代码编译后的二进制库文件和程序接口,和静态链接库不同的是,程序在编译时并不链接动态链接库的执行体,而是在文件中保留一个调用标记,在程序运行时才将动态链接库文件 ...
- java matlab混合编程之返回值Struct类型
java matlab混合编程的时候当返回值是Struct类型(matlab中的返回类型)如何来取得(java中)其值? 上网找,看到这个网页:http://www.mathworks.cn/cn/h ...
- WPF(C#)与MATLAB混合编程
WPF(C#)与MATLAB混合编程 WPF可以为开发者提供便捷地构建用户交互界面的解决方法,而matlab则在科学计算方面有着无与伦比的优势,因此在一些需要将科学算法转换为应用软件的项目中,需要应用 ...
- VC 与Matlab混合编程之引擎操作详解
Visual C++ 是当前主流的应用程序开发环境之一,开发环境强大,开发的程序执行速度快.但在科学计算方面函数库显得不够丰富.读取.显示数据图形不方便. Matlab 是一款将数值分析.矩阵计算.信 ...
- VS/Qt C++和Matlab混合编程
最近两天在搞C++和Matlab混合编程,这个中间过程真是让人心酸啊,最后还是搞定成功!现在把这个过程记录一下. 首先自己的电脑本来就安装着matlab2013b,按着网上的说法首先需要输入!mcc, ...
- C++和MATLAB混合编程求解多项式系数(矩阵相除)
摘要:MATLAB对于矩阵处理是非常高效的,而C++对于矩阵操作是非常麻烦的,因而可以采用C++与MATLAB混合编程求解矩阵问题. 主要思路就是,在MATLAB中编写函数脚本并使用C++编译为dll ...
- matlab混合编程向导(vc,vb,.net...)
一.matlab与vc混编 1.通过mcc将matlab的m文件转化为cpp,c文件或dll供vc调用: 这方面的实现推荐精华区Zosco和ljw总结的方法(x-6-1-4-3-1和2) ...
- Matlab混合编程
Matlab混合编程 混合编程目的 在Matlab中采用混合编程目的主要包括 利用已有的函数库,避免重复工作 加速计算,特别是减少循环所用时间 利用GPU等进行异构编程 混合编程方法-mex函数 目前 ...
- C#Matlab混合编程类 初始化问题解决方法
************** 异常文本 ************** System.TypeInitializationException: “myPlus.matClass”的类型初始值设定项引发异 ...
随机推荐
- fluent求平均温度、最高低温度和平均传热系数【转载】
摘自<ANSYS FLUENT技术基础与工程应用:流动传热与环境污染控制领域> 一.平均温度的计算: 双击导航栏中Result下方的Report进入Report任务页面,双击其中的Volu ...
- ssm 项目记录用户操作日志和异常日志
借助网上参考的内容,写出自己记录操作日志的心得!! 我用的是ssm项目使用aop记录日志:这里用到了aop的切点 和 自定义注解方式: 1.建好数据表: 数据库记录的字段有: 日志id .操作人.操作 ...
- JS中注入eval, Function等系统函数截获动态代码
正文 现在很多网站都上了各种前端反爬手段,无论手段如何,最重要的是要把包含反爬手段的前端javascript代码加密隐藏起来,然后在运行时实时解密动态执行. 动态执行js代码无非两种方法,即eval和 ...
- 生产者消费者模型Java实现
生产者消费者模型 生产者消费者模型可以描述为: ①生产者持续生产,直到仓库放满产品,则停止生产进入等待状态:仓库不满后继续生产: ②消费者持续消费,直到仓库空,则停止消费进入等待状态:仓库不空后,继续 ...
- NGINX实现咏南跨平台中间件集群
NGINX实现咏南跨平台中间件集群 首先要开启咏南LINUX中间件. 1)编辑usr/local/nginx/conf/nginx.conf #user nobody;worker_processe ...
- Java从指定URL下载文件并保存到指定目录
1.基本流程 当我们想要下载网站上的某个资源时,我们会获取一个url,它是服务器定位资源的一个描述,下载的过程有如下几步: (1)客户端发起一个url请求,获取连接对象. (2)服务器解析url,并且 ...
- android studio: 对齐成员变量及链式方法
"File"-"Settings"-"Editor"-"Java"-"Wrapping and Braces& ...
- Could not attach to pid : "xx"最近启动Xcode运行项目都会出现这个问题,再次启动或者多启动几次,就可以正常运行工程了。
最近启动Xcode运行项目都会出现这个问题,再次启动或者多启动几次,就可以正常运行工程了. 普及一下:PID(进程控制符)英文全称为Process Identifier,它也属于电工电子类技术术语. ...
- Visio 的键盘快捷方式
https://support.office.com/zh-cn/article/Visio-的键盘快捷方式-ee952f31-7e3e-4564-8116-f3ecbb733cc1 https:// ...
- 关于[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] 的解释
关于[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)] 的解释 [StructLayout(LayoutKind.Sequentia ...