VC++如何利用Matlab2014b的图形引擎进行绘图

VC++如何利用Matlab的图形引擎

在Visual C++ 2015 工程中使用 Matlab2014b 提供的图形引擎进行绘图的详细过程。

问题来源:

有时候用C++写一些演示程序,有数据可视化的需求。一般来讲,在Window下无非这么几种解决方案:用MFC,QT之类的框架,用GDI之类的系统API,用DirectX API或者Open GL。非主流一点的把数据写成Json写成私有格式,然后前端技术BlahBlah之类的玩意以网页的方式可视化。当然也可以用一些别的软件提供的API,比如,Matlab。

为啥有这个需求呢?首先上面那些乱七八糟的东西,用来做可视化演示都不能叫重复造轮子了,简直就是在种橡胶树。如果你看过MSDN上用DirectX2D画长方形的演示,就会知道什么叫蛋疼了,到处充斥着细节,如果只是用来做个算法演示,模拟之类的东西真是杀鸡用牛刀,蛋疼无比。Matlab的高级图形引擎早就提供了一整套完整的解决方案,不用真是太可惜了。尤其是Matlab2014b里面,图形引擎换过了,画出来的图比以前漂亮多了。用来做Demo简直不能更方便。

新版图形引擎的效果:

前期准备:

我的测试环境是: Window Technical Preview(Win10) + Visual Studio 2015 Preview + Matab 2014 64位; 当然其实Win8+VS2013的组合肯定也可以。

我猜大多数试过的这种绘图方式的人,都层掉进过平台,编译、装载、链接的大坑里。因此在此分享掉坑经验,以便他人少走弯路。

原理:

用C++调用Matlab图形引擎,主要是利用COM组件服务。将Matlab作为COM Server,接受Client应用程序的请求。Matlab的m脚本是一种解释性语言,因此大多数调用都是直接通过传递命令字符串的eval方法实现的。那么具体流程呢,就是用户的C++ 程序,Include了Matlab提供的头文件engine.h;参考了Matlab提供的静态库文件libeng.lib,libmx.lib;引用了Matlab提供的动态链接库文件(位于…..\MATLAB\R2014b\bin\win64中的一大票Dll文件)。头文件,静态库文件,动态链接库文件是什么,这个就不科普了。推荐《程序员的自我修养》。

具体过程:

废话不多说,让我们来试一试吧,先把测试用的代码贴出来好了。

 1 #include<cstdlib>
 2 #include <cstdio>
 3 #include<cstring>
 4 #include"engine.h"
 5
 6 const int BUFFER_SIZE = 1024;
 7 char buffer[BUFFER_SIZE];
 8
 9 void test()
10 {
11     Engine* ep;
12     mxArray *x1 = NULL;
13     mxArray *y1 = NULL;
14     if ((ep = engOpen("")) == NULL)
15     {
16         printf("Engine Fail");
17     }
18     engOutputBuffer(ep, buffer, BUFFER_SIZE);
19     printf("Init Success");
20
21     double x[5] = { 1.0, 2.5,3.7,4.4,5.1 };
22     double y[5] = { 3.3,4.7,9.6,15.6,21.3 };
23     x1 = mxCreateDoubleMatrix(1, 5, mxREAL);
24     y1 = mxCreateDoubleMatrix(1, 5, mxREAL);
25
26     memcpy((void *)mxGetPr(x1), (void *)x, sizeof(x));
27     memcpy((void *)mxGetPr(y1), (void *)y, sizeof(y));
28
29     engPutVariable(ep, "x", x1);
30     engPutVariable(ep, "y", y1);
31
32     engEvalString(ep, "plot(x,y)");
33     getchar();
34     engClose(ep);
35 }
36
37 int main()
38 {
39     test();
40 }

但是不要急,直接复制黏贴进一个新项目直接Build是铁定Fail的。实际上项目属性的配置,要比单纯写代码麻烦多了。

第一步:

确认你的Matlab版本,是64位还是32位的。32位不用改,不过一般Matlab装的都是64位的吧?那么,就在Build – Configuration Manager中建立一个新的配置文件:Active Solution Paltform活动平台记得选择x64,下面选择复制自Win32不用管它。

这一步是一个大坑,因为绝大多数Visual C++程序都是以32位平台作为目标编译的,所以如果有32位平台相关的代码,Build就会尿掉。所以注意一下自己用到的库吧,如果你知道自己在做什么那是最好了。

第二步:

设置VC++目录。在解决方案管理器中选中当前的项目,点右键菜单-属性,或者直接Alt+Enter打开属性面板。总之选中VC++ 目录,右边就会出来一大堆要你填的东西。要关注的东西有三个:第一个 可执行程序目录,第二个 包含目录, 第四个,库目录。这三个东西分别对应dll文件的位置,头文件的位置,lib文件的位置。

具体位置呢,可以看图中,我的Matlab是安装到默认位置的,安装到别的位置可以改一下前缀。这些目录地址就是告诉编译器和链接器到哪儿去找要用的东西。

C:\Program Files\MATLAB\R2014b\bin\win64;

C:\Program Files\MATLAB\R2014b\extern\include;

C:\Program Files\MATLAB\R2014b\extern\lib\win64\microsoft;

看名字就知道了,bin,include,lib。

第三步:

C++还有个坏毛病,你得手动告诉链接器我用了哪些库文件。上面填库目录那里只是告诉链接器,如果需要库文件,你来这些地方找一找。不过链接器确实还需要知道你用的库的名字。这里Matlab绘图需要用到两个库: libeng.lib和libmx.lib。一个是Matlab引擎,一个是Matlab的矩阵库。怎么弄呢?在项目属性中选择Linker(链接器) -> Input 在右边的额外依赖项中加上两个:libeng.lib , libmx.lib就可以了。

第四步

基本上改了平台,填了目录,填了库名,就可以万事大吉了。但是有时候往往还是会有各种破事,比如提示libeng.dll找不到啊之类的。这时候呢,可以通过修改环境变量的方式来解决这个问题。C:\Program Files\MATLAB\R2014b\bin\win64; 把原来可执行程序的目录加入到系统的PATH环境变量中,然后记得重启。。。。就可以解决问题了。

第五步

配置问题到此已经解决了,现在终于可以试试身手了。在项目中新建一个cpp文件,把代码复制进去。Run一下看看?Matlab的C引擎API非常简单。数来数去就是那么几个方法,都以eng开头:

engOpen, engClose一看就知道干嘛用的。engPutVariable, engGetVariable是用来存取工作区的变量的。然后就是万能的engEvalString。参数就是一个Engine指针和命令字  符串。就跟在Matlab里面敲的命令一样。

然后如果需要用Get/Put Variable,需要用到矩阵库libmx.lib中的内容,就是创建一个double数组,创建一个mxArray对象,一看就能明白的东西是吧,详细的内容Matlab的Doc里都有,就不赘述了。

噢吼吼,是不是很棒啊。虽然只是很简单的效果。不过用好了却是妙用无穷啊,可以自己写个类包装一下方便以后使用。

另外呢,还有一个小技巧。每次运行你的小程序的时候吧,总是会开一个新的Matlab COM server实例。冷启动得快十秒,热启动也要好几秒。真是慢的可以。有一个解决方案呢,就是启动一个Matlab Automation Server。这样每次运行程序时,它就会主动链接到这个手动启动的实例上请求服务而不是自己搞出个新的出来了,会快很多。

怎么做呢?很简单,启动Matlab,加个命令行参数/Automation。在CMD或者Powershell中输入matlab /Automation 就行了。

大概就是这样。

时间: 2024-10-24 20:04:50

VC++如何利用Matlab2014b的图形引擎进行绘图的相关文章

VC中利用多线程技术实现线程之间的通信

文章来源:[url]http://www.programfan.com/article/showarticle.asp?id=2951[/url] 当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软件是当今普遍采用的方法,进程和线程的概念的出现,对提高软件的并行性有着重要的意义.现在的大型应用软件无一不是多线程多任务处理,单线程的软件是不可想象的.

窗体的Alpha通道透明色支持(一旦 Form 被定义为利用 LayeredWindow ,窗口的绘图不再响应沿用多年的 WM_Paint 消息)

参考: http://www.delphibbs.com/delphibbs/dispq.asp?lid=2190768 Windows 2000后,为了支持类似MAC界面的Alpha通道混合效果,提供了GDI+,提供了很多的界面功能函数,可以实现很好的界面效果.例如可以使用UpdateLayeredWindow来实现窗体的颜色透明.但是一旦 Form 被定义为利用 LayeredWindow ,窗口的绘图不再响应沿用多年的 WM_Paint 消息. UpdateLayeredWindow(hw

深入浅出CChart 每日一课——快乐高四第十一课 不离不弃,利用CChartWnd实现多区域绘图

笨笨在前面的课程里面提到,在一个窗口上不能粘多个CChartWnd,否则图像不正常,故而在高四6到8课,均使用CChart类,实现了在普通窗口.对话框窗口.DuiLib窗口上的多区域绘图. 使用CChart类必须手动处理消息,而采用CChartWnd类省去了处理消息的步骤,编程更为简便. 近几天笨笨进行了一些改进,采用CChartWnd类也可以在一个窗口上多区域绘图了. 1 首先按照前面的步骤建立一个基于Win32 Application的程序,名为LessonA11. 2 在WndProc函数

python 利用matplotlib中imshow()函数绘图

matplotlib 是python最著名的2D绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地进行制图.而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中.通过简单的绘图语句,就可以绘制出高质量的图了. 这里我们就主要讲一下inshow()函数的使用. 首先看一下怎么基本画图的流程: import matplotlib.pyplot as plt #创建新的figure fig = plt.figure() #必须通过add_subplot()创建一个或多个绘图 ax

MFC GDI绘图基础

一.关于GDI的基本概念 什么是GDI? Windows绘图的实质就是利用Windows提供的图形设备接口GDI(Graphics Device Interface)将图形绘制在显示器上. 在Windows操作系统中,动态链接库C:/WINDOWS/system32/gdi32.dll(GDI Client DLL)中定义了GDI函数,实现与设备无关的包括屏幕上输出像素.在打印机上输出硬拷贝以及绘制Windows用户界面功能.在Visual C++6.0中的头文件C:/Program Files

MFC中的GDI绘图&lt;转&gt;

一.关于GDI的基本概念 什么是GDI? Windows绘图的实质就是利用Windows提供的图形设备接口GDI(Graphics Device Interface)将图形绘制在显示器上. 在Windows操作系统中,动态链接库C:\WINDOWS\system32\gdi32.dll(GDI Client DLL)中定义了GDI函数,实现与设备无关的包括屏幕上输出像素.在打印机上输出硬拷贝以及绘制Windows用户界面功能.在Visual C++6.0中的头文件C:\Program Files

孙鑫视频VC++深入详解学习笔记

Lesson1: Windows程序运行原理及程序编写流程 Lesson2: 掌握C++基本语法 Lesson3: MFC框架程序剖析 Lesson4: 简单绘图 Lesson5: 文本编程 Lesson6: 菜单编程 Lesson7: 对话框编程 Lesson9: 定制应用程序的外观 Lesson10: 绘图控制 Lesson11 图形的保存和重绘 Lesson12 文件操作 Lesson 13: 文档串行化 Lesson14 网络编程 Lesson 15 多线程 Lesson 16 线程同步

MFC中的GDI绘图(1)

一.关于GDI的基本概念 什么是GDI         Windows绘图的实质就是利用Windows提供的图形设备接口GDI(Graphics Device Interface)将图形绘制在显示器上. 在Windows操作系统中,动态链接库C:\WINDOWS\system32\gdi32.dll(GDI Client DLL)中定义了GDI函数,实现与设备无关的包括屏幕上输出像素.在打印机上输出硬拷贝以及绘制Windows用户界面功能.在Visual C++6.0中的头文件C:\Progra

孙鑫视频VC++深入详解学习笔记(全)

Lesson1: Windows程序运行原理及程序编写流程 窗口产生过程,句柄原理,消息队列,回调函数,窗口关闭与应用程序退出的工作关系,使用VC++的若干小技巧,stdcall与Lessonecl调用规范的比较,初学者常犯错误及注意事项. 1.       Windows API与Win32 SDK 操作系统提供了各种方便开发Windows应用程序的编程接口,所的函数都在Windows.h头文件中声明.Win32 SDK(Software Development Kit): 即Windows