VC编程范文(精选9篇)
VC编程 第1篇
摄影测量与遥感所获取数字影像, 尤其是近景摄影测量采用非量测相机获取的影像, 不能直接应用于测量, 首先需要经过图像处理, 形成满足测量要求的图像。
图像几何变换是图像处理的基础。经过几何变换, 使图像易于处理, 有利于特征提取和对图像信息的理解。
1 原理介绍
1.1 图像平移
平移是指将图像中所有的点都按照指定的平移量水平、垂直移动。设 (x0, y0) 为原图像上的一点, 图像水平平移量tx, 垂直平移量为ty, 则平移后点 (x0, y0) 的坐标变为 (x1, y1) 。
(x0, y0) 与 (x1, y1) 之间的关系为:x1=x0+tx;y1=y0+ty。
平移后图像上的一点是由原图像上某点经过平移得到的, 因此平移后图像中每个像素的颜色是由原图像中对应像素颜色确定的。如新图中的 (0, 0) 点的颜色和其在原图中的对应点 (-tx, -ty) 处的一样。
1.2 图像旋转
图像旋转通常是以图像的中心为圆心, 按顺时针方向旋转。
设旋转前一点坐标 (x0, y0) , 旋转a角度后对应点坐标 (x1, y1) , 则以矩阵的形式表示:
1.3 图像缩放
假设放大因子为ratio, 缩放的变换矩阵为:
由于放大图象时产生了新的象素, 缩小时合并了像素, 变换后图像上点与原图点不存在一一对应的关系, 所以采用的做法是找与之最临近的点。
2 算法设计
2.1 图像平移
图像几何变换都是基于像素处理的。
首先打开原始图像, 获取图像信息。
第二步设置水平平移量和垂直平移量。根据平移量和原图像高度宽度, 计算平移后图像的宽度和高度:
NWidth=l Width+ (long) f XMove;NHeight=l Height+ (long) f YMove。
第三步采用行列循环方式, 计算新图像中每个像素对应于原图像的像素, 将原图像的像素灰度值或RGB颜色值赋值给新图像的像素。对于原图像中没有的对应点的像素, 将其灰度值设为0 (白色) 。以8位图为例, 程序如下:
2.2 图像旋转
首先打开原始图像, 获取图像信息, 包括图像的高度、宽度、调色板或者RGB值等信息。
第二步因为图像旋转采用以图像中心为原点的坐标系, 因此首先进行坐标转换, 计算原图四角点在以图像中心为原点的旋转坐标系中的坐标, 并根据旋转角度计算旋转后图像四角坐标, 利用旋转后图像四角点计算新图像高和宽。
第三步采用行列循环方式, 计算新图像中每个像素对应于原图像的像素, 将原图像的像素灰度值或RGB颜色值赋值给新图像的像素。对于原图像中没有的对应点的像素, 将其灰度值设为0 (白色) 。
2.3 图像缩放
首先打开原始图像, 获取图像信息, 包括图像的高度、宽度、调色板或者RGB值等信息。
第二步设置缩放参数, 并根据原图像宽、高计算经过缩放后的图像的宽、高。
第三步采用行列循环方式, 计算新图像中每个像素对应于原图像的像素, 将原图像的像素灰度值或RGB颜色值赋值给新图像的像素。对于原图像中没有的对应点的像素, 将其灰度值设为0 (白色) 。算法与平移和旋转类似, 在此不在详述。
3 实现方法与过程
(1) 创建一个MFC多文档工程, 并设置滚动视图模式。
(2) 在Doc类中声明一个HDIB类型的的成员变量m_h DIB, 并利用Class Wind类向导为Doc类添加On Open Document和On SaveDocument两个函数, 添加代码, 调用DIB.dll中封装好的open和save函数, 在On Draw函数中调用Draw (p DC, p Doc->m_h DIB) , 实现图像读取和保存功能。
(3) 添加菜单“平移”“旋转”“缩放”, 并为菜单添加相应的对话框资源, 用以设置相关参数。利用Class Wind类向导为各个菜单添加消息处理函数, 为每个对话框添加对话框类。
(4) 在对话框类中添加相应参数变量并初始化。为每个菜单消息处理函数编写函数体, 使之实现相应功能。
摘要:数字图像处理是摄影测量的基础, 图像几何变换是图像处理最基本的内容。文章就利用VC编程实现图像的平移、旋转、缩放的原理、算法和实现过程进行详细论述。
关键词:VC,数字图像,平移,旋转,缩放
参考文献
[1]孙家柄.遥感原理与应用[M].武汉:武汉大学出版社, 2006.
[2]王育坚.Visual C++面向对象编程教程[M].北京:清华大学出版, 2006.
[3]贾永红.数字图像处理[M].武汉:武汉大学出版社, 2004.
VC图像编程教案 第三章 第2篇
VC图像编程教案 第三章
VC图像编程教案 第三章 3 DIB类的高级应用。 3.1 BMP文件结构 BMP文件头数据结构含有BMP文件的类型、文件大小和位图起始位置等信息。 typedef struct tagBITMAPFILEHEADER { WORDbfType; // 位图文件的类型,必须为BM DWORD bfSize; // 位图文件的大小,以字节为单位 WORDbfReserved1; // 位图文件保留字,必须为0 WORDbfReserved2; // 位图文件保留字,必须为0 DWORD bfOffBits; // 位图数据的起始位置,以相对于位图 // 文件头的.偏移量表示,以字节为单位 } BITMAPFILEHEADER; BMP位图信息头数据用于说明位图的尺寸等信息。 typedef struct tagBITMAPINFOHEADER{ DWORD biSize; // 本结构所占用字节数 LONGbiWidth; // 位图的宽度,以像素为单位 LONGbiHeight; // 位图的高度,以像素为单位 WORD biPlanes; // 目标设备的级别,必须为1 WORD biBitCount// 每个像素所需的位数,必须是1(双色), // 4(16色),8(256色)或24(真彩色)之一 DWORD biCompression; // 位图压缩类型,必须是 0(不压缩), // 1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一 DWORD biSizeImage; // 位图的大小,以字节为单位 LONGbiXPelsPerMeter; // 位图水平分辨率,每米像素数 LONGbiYPelsPerMeter; // 位图垂直分辨率,每米像素数 DWORD biClrUsed;// 位图实际使用的颜色表中的颜色数 DWORD biClrImportant;// 位图显示过程中重要的颜色数 } BITMAPINFOHEADER; typedef struct tagRGBQUAD { BYTErgbBlue;// 蓝色的亮度(值范围为0-255) BYTErgbGreen; // 绿色的亮度(值范围为0-255) BYTErgbRed; // 红色的亮度(值范围为0-255) BYTErgbReserved;// 保留,必须为0 } RGBQUAD; 颜色表中RGBQUAD结构数据的个数有biBitCount来确定: 当biBitCount=1,4,8时,分别有2,16,256个表项; 当biBitCount=24时,没有颜色表项。 位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下: typedef struct tagBITMAPINFO { BITMAPINFOHEADER bmiHeader; // 位图信息头 RGBQUAD bmiColors[1]; // 颜色表 } BITMAPINFO; 3.2 DIB类的Read函数: BOOL CDib::Read(CFile* pFile) { // 1. read file header to get size of info hdr + color table // 2. read info hdr (to get image size) and color table // 3. read image // cant use bfSize in file header Empty; int nCount, nSize; BITMAPFILEHEADER bmfh; try { nCount = pFile->Read((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER)); if(nCount != sizeof(BITMAPFILEHEADER)) { throw new CException; } if(bmfh.bfType != 0x4d42) { throw new CException; } nSize = bmfh.bfOffBits - sizeof(BITMAPFILEHEADER); m_lpBMIH = (LPBITMAPINFOHEADER) new char[nSize]; m_nBmihAlloc = m_nImageAlloc = crtAlloc; nCount = pFile->Read(m_lpBMIH, nSize); // info hdr & color table ComputeMetrics(); ComputePaletteSize(m_lpBMIH->biBitCount); MakePalette(); m_lpImage = (LPBYTE) new char[m_dwSizeImage]; nCount = pFile->Read(m_lpImage, m_dwSizeImage); // image only } catch(CException* pe) { AfxMessageBox(Read error); pe->Delete(); return FALSE; } return TRUE; } 3.3 DIB类的Write函数: BOOL CDib::Write(CFile* pFile) { BITMAPFILEHEADER bmfh; bmfh.bfType = 0x4d42; // BM int nSizeHdr = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries; bmfh.bfSize = 0; //bmfh.bfSize = sizeof(BITMAPFILEHEADER) + nSizeHdr + m_dwSizeImage; // meaning of bfSize open to interpretation (bytes, words, dwords?) -- we wont use it bmfh.bfReserved1 = bmfh.bfReserved2 = 0; bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries; try { pFile->Write((LPVOID) &bmfh, sizeof(BITMAPFILEHEADER)); pFile->Write((LPVOID) m_lpBMIH, nSizeHdr); pFile->Write((LPVOID) m_lpImage, m_dwSizeImage); } catch(CException* pe) { pe->Delete(); AfxMessageBox(write error); return FALSE; } return TRUE; } 3.4 明确图像文件 CFile CDib类三者之间的关系 3.5 尝试直接用CDib类的m_lpImage成员读取图像数据。 3.6 尝试通过Write保存图像到另一个位置 3.7 尝试通过Write重写原图像文件(注意保存)
利用VC编程实现网络状态在线监测 第3篇
1 VC编程概述
VC是一种软件集成开发环境,它是由微软公司开发完成的,换个角度理解就是基于C++的一个开发平台。VC是基于Windows平台的一种C++编程环境,包括MFC、ATL、COM等,此外还具有Windows平台的特性。基于Windows下的VC编程需要掌握Windows的消息机制和回调(callback)函数的原理。MFC是需要理解文档视图类的结构、窗口类的结构、消息流向等的Win32API的包装类。COM是一个需要掌握其基本原理代码共享的二进制标准。除此之外,VC是一个主流的开发平台,它不属于语言。如果将C++视为工业标准,那VC则是遵循工业标准的前提下衍生出来的某种厂商标准的操作系统平台。VC是一种包括WIN API和MFC方式的在Windows平台下开发的VC应用程序,MFC是对传统的WIN API再次封装,其结构相比较简单,所以MFC的开发模式备效率优势更加明显。
2 VC编程网络在线监测功能的模块化
要实现类似MFC的网络状态在线监测和数据分析,就必不可少的需要借助VC相应的功能,例如强大的网络通信板块、多线程开发板块等。在监测软件的开发过程中,充分利用VC成熟的开发资源平台,开发建立有针对性的应用功能模块,做到开发效率和软件质量的双赢,其主要包括以下环节:(1)功能模块设计。MFC应用的实际上是TCP/IP协议组主要用在IP主机、路由器之间传递控制消息的一个子ICMP协议。Windows给予了ASMP.dll的支持,能够从VC中直接引用,但是不支持移植,另外无法控制网络信息的数据包。因此,在基于工程中包含adewfxsock.hfg库的前提下,借助VC技术能够直接针对套接字(socket)进行有效编程,勾选了一个和MFC程序一样发送32字节的数据信息,得到数据包大小和TTL值的回馈,编程过程及系统调用时序,如图1所示。(2)网络状态在线监测。首先,构建套接字符串,然后指定使用的ICMP协议。其次,发送air_ICMP数据包,初试化ECHORHHGEQUEST的types为9的响应请求指令,然后通过系统调用发送ICMPSD数据,并设置目标IP地址。(3)监测套接字符串网络在线状态,检测一个或多个套字符串的状态。(4)响应数据的识别,判断网络在线监测状态。最终,在回馈的数据当中包含了该次在线监测的结果。至此,同MFC方式一样,通过VC编程实现网络状态在线监测。
3 VC多线程编程网络状态在线监测
进程和线程都可以被看作操作系统的概念。通过应用程序执行实例的过程被称作进程,私有的虚拟地址空间、代码、数据和其他各种系统资源共同构成了每个进程,并且在运行模拟的过程中进程的终止会销毁创建的资源,使得进程终止时,所使用的系统资源获得释放或关闭。线程以一个执行单元的形式存在于进程内部。系统创建好进程后,同时也就启动了以函数地址形式执行的进程的主执行线程,并且,Windows系统也将接受来自主执行线程的指令。主执行线程的行为状态最终决定了进程的行为状态。每一个进程都需要一个由系统自动创建的而不需要用户操作的线程。用户可以根据网络监测具体项目,来创建对应的程序在同一个进程中所需要的多个线程。网络状态在线监测模块,在不需要用户界面交互的条件下,能够自动获取所需要的目标IP地址数据,并通过该地址数据创建单独的线程,定时实现后台运行在线网络状态监测。线程之间的通讯之所以方便,是因为在一个进程中的所有线程都在该进程的虚拟地址空间中,共同使用这些虚拟地址空间、全局变量和系统资源,最终使得多线程技术的应用广泛流行。除此之外,为了减少某项任务的长时间占用CPU,多线程可以通过并行处理的方式来实现此功能。可以通过适当的人机交互界面和配置数据管理的方式,来搭建一个完整的VC编程控制的网络在线监测应用系统。该系统系统功能包括网络监测完成网络节点通阻状态的存储;状态显示完成网络节点通阻状态的监测;节点管理完成网络节点通阻状态的分析;指标分析完成网络节点通阻状态的显示。网络状态在线状态的显示是通过客户端图形模式和动态网页模式构成。客户端图形模式采用的是可以对系统监测周期和节点属性等参数进行配置的C/S架构,除此之外,该构架还可以查看节点监测通阻状态和大数据的整理与分析,最终得到故障原因及解决方案。而浏览器网页模式主要用于查看节点状态和指标分析数据。
4 结束语
基于VC编程充分利用了MFC总线的多节点、远距离、实时性好等优点,设计出了一套高效实用的网络在线监测系统,而且该系统具有直观实用的界面和高效简便的编程方式,在监测系统的应用很广泛。
参考文献
[1]赵立群,吴霞,孙岩.计算机网络管理与安全[M].北京:清华大学出版社,2014.
[2]罗莉琴,詹祖桥,黄辉等.Windows网络编程[M].北京:人民邮电出版社,2011.
[3]潘磊,裴斐.一种面向大规模网络拓扑发现的研究[J].计算机工程与应用,2010,46(19).
[4]DAVID.VISUAL C++6编程宝典[M].北京:电子工业出版社,2005.
浅析VC与Matlab联合编程 第4篇
作者:邓科
在“浅析VC与Matlab联合编程<一>”和“浅析VC与Matlab联合编程<二>”中介绍了matcom,这个工具可以将用matlab写的m文件翻译成C++文件,或者是可执行文件(exe)或库文件(dll),
浅析VC与Matlab联合编程
。但是matcom在很多方面也有限制,比如,对struct等类的支持有缺陷,部分绘图语句无法实现或得不到准确图象,尤其是三维图象。
实际上VC与matlab的接口实现方法有很多种,matcom只是其中一种,本文再介绍一种比较容易实现的方法:COM接口方法。COM(Compponent Object Model组件对象模型)是一项比较复杂的技术,详细讲的话几本书也讲不完,所以在这里不作介绍,本文通过一个例子详细介绍如何在matlab下做COM组件,以及如何在VC中调用COM组件。
首先在Matlab编辑器里编辑m函数文件:启动matlab->File->New->M-file函数内容如图1:该函数无输入输出参数,文件保存为huatu.m。
图1 m函数huatu.m
在matlab下建立COM组件,步骤如下:
1、在matlab command window 输入如下命令:
>>comtool
出现com编辑界面,如图2:
图2 com组件编辑界面
2、新建工程:File->New Project…,如图3。
图2 com组件属性设置
3、设置组件属性,在”Component name“项中填写组件名称”component“,这时候会自动生成类”component“,在”Class name“项中填写类名称”huatu“,如图4,
图4 com组件属性设置1
为了便于区分,选中”Classes“中的”component“,点击“remove”按钮,将类component移除,再点击”Add>>“添加新类huatu,结果如图5,
点击”OK“,接下来出现一个对话框,选择”Yes“.
图5 com组件属性设置2
4. 添加文件:选中左边工作区的”huatu“,点击Project->Add File…,选择已经编辑好的函数文件huatu.m,如图6。需要注意的是m文件必须是m函数,否则会报错,如果是m脚本文件的话,只需要改为无输入输出参数的m函数即可。
图6 添加m文件
5、生成 com组件:点击Build->COM Object…,结果如图7。
图7
com组件已经由matlab做好,默认的保存位置为:matlab安装位置workcomponent。
VC中调用COM组件,步骤如下:
1、在VC中建立名为ComHuaTu的基于对话框的MFC(exe)。
2、面板上添加一个名为“画图”的button按钮,如图8。
图7 工程界面
3、将component_idl.h 和component_idl_i.c文件拷贝到VC建立的工程ComHuaTu目录下。两文件默认目录为workcomponentsrc
4、将上面两文件加入工程:工程->添加工程->Files,选择刚刚拷到目录下的component_idl.h 和component_idl_i.c文件。
5、将目录/extern/include/下的mwcomtypes.h拷贝到工程ComHuaTu目录下,并加入到工程中,方法同上。
6、为程序添加头文件component_idl.h 、component_idl_i.c和mwcomtypes.h,结果如图9
图9 添加头文件
7、按钮画图函数添加代码:
图10 添加按钮函数代码
VC编程 第5篇
MATLAB和VC++是目前应用最广泛的仿真和开发软件, 它们都有各自的优缺点。MATLAB是一种高性能的数值计算和可视化编程软件, 在数值分析、信号处理、和图形处理等方面具有广泛的应用, 特别是在图像处理方面更具有明显的优势[1]。但缺点是它的执行效率低, 速度慢;而且它不能脱离其运行环境, 可移植性差。Visual C++是一种面向对象的可视化编程语言, 利用它可以方便快捷的开发出各种界面友好的软件系统, 此外Visual C++与其他高级语言相比还具有很高的代码执行效率。但是它在数值运算和数字图像处理等方面的能力远远低于MAT-LAB语言, 程序编写得不好就会影响到整个系统的运行速度[2][3]。由上可见, 如果把MATLAB与VISUAL C++在数值运算、图像处理的应用中结合起来, 不仅可以完全满足系统在数值计算和图像处理的需求, 而且还可以提高软件的开发效率和产品质量。因此, MTALAB与VC++的混合编程的研究在实践中具有很高的实用价值。
2、VC++与MATLAB混合编程的基本方法
VC++与MATLAB结合常用的方法有五种[4]: (1) Mex文件; (2) 用Matcom将MATLAB的M文件编译成Cpp代码并嵌入到VC++中; (3) 使用MATLAB提供的计算引擎函数; (4) 利用MAT-LAB提供的MCC命令生成与MATLAB文件对应的基于C语言或C++语言的包裹文件, 再嵌入到VC++中; (5) 在VC++中直接调用MATLAB C/C++数学函数库。由于篇幅原因, 本文主要讨论 (1) 和 (3) 两种方式。
2.1 Mex
Mex文件是MATLAB调用别的语言编写的程序或算法的接口。MATLAB通过它就可以直接调用或链接由其它语言编写的算法例程, 提高了程序的运行效率。
Mex文件其实质是一种特殊的动态链接子程序, 它的源代码一般采用C语言, 根据一定的接口规范编写而成。Mex文件可以像MATLAB的普通函数一样被调用, 具有很快的执行速度。它主要应用在以下几个方面: (1) 对于某些已开发的C语言子程序, 可以通过MEX方式在MATLAB环境中直接调用, 而不必将其转化为M文件而重新编写。 (2) 瓶颈计算 (如循环迭代) 在MATLAB中的运行速度较慢, 可以仅将这一部分转化为C代码, 并通过调用其相应的Mex文件来提高效率。 (3) 通过Mex文件可直接控制硬件, 如A/D采集卡, D/A输出卡等, 以弥补MAT-LAB的不足。
2.1.1 配置测试
在运行mex程序之前, 必须在MATLAB中用"mex-setup"命令, 对mex程序的编译器选项进行设置。设置按照mex命令的提示进行选择, 就可以配置好编译器的配置文件。配置完成后可以编译一个MEX文件进行测试。在MATLAB命令窗口中输入:
cd MATLAB根目录externexamplesmex/*把yprime.c所在目录指定为当前目录*/
mex yprime.c/*由yprime.c生成yprime.dll*/
如果配置好了编译器的默认文件, 那么yprime.dll文件已经生成, 到yprime.c所在的目录下就可以看到这个文件。在命令窗口输入:yprime (1, 1:4)
得到结果:ans=2.0008.96854.000-1.0947
如果配置不成功, 系统就会报错, 根据错误原因再重新配置编译器的默认配置文件。
2.1.2 用C语言编写Mex源文件
C语言的Mex源程序主要由两部分组成, 第一部分称为入口子程序, 其作用是将MATLAB与被调用的外部子程序之间建立通信联系, 第二部分称为计算子程序, 即在Mex文件中完成计算功能的程序代码, 它由入口子程序调用。下面以简单的选择排序程序为例说明MEX文件编写的基本框架和规范。
然后对sort.c程序进行编译链接, 运行生成sort.dll。随后就可以对其进行各种测试。如:
从上例中可以清楚看到应用Mex技术可以方便地在MAT-LAB中调用已编好的C程序。
2.2 MATLAB引擎及其接口调用
2.2.1 MATLAB引擎
MATLAB引擎 (MATLAB Engine) 是指一组MATLAB提供的接口函数 (Engine API函数) 。它采用客户机/服务器 (Client/Server) 计算模式, 并且支持C语言。这种方法实现较为简单, 不需要启动整个MATLAB程序, 只需要嵌入必要的MATLAB Engine库, 可大大的节省系统资源。
MATLAB Engine提供了一组MATLAB API函数[5], 它有C和FORTRAN两个版本, 表1列出了其部分C语言函数, 它们的申明放在头文件"engine.h"中。
2.2.2 程序的实现
由于MATLAB引擎的强大功能, 在实际应用中, 经常用基于MATLAB引擎的VC++与MATLAB混合编程方法来显示和处理数字图像。下面给出具体的实现过程。
(1) 在Visual C++中新建一个基于对话框MFC AppWizard (EXE) 类型的文档。
(2) 设置工作的环境。使用菜单Tools/Options设置属性页, 进入Directories页面, 选择Show directories for下拉框中的Include files, 加入路径 (假定MATLAB安装在F盘下) :F:MATLABexternincludecpp F:MATLABexterninclude
(3) 选择library files, 加入如下路径:F:MATLABexternlibwin32Microsoftmsvc60
(4) 打开菜单Project/settings, 选择Link页面, 在编辑框Object/Library modules中添加文件名:libeng.lib、libmx.lib、libmat lib MATLAB.lib libmex.lib
(5) 在工程中的对话框添加控件, 为相应的控件添加二个变量:Int m_lvbo (滤波的类型) CString m_name (要处理的图像文件的路径) .
程序部分代码如下:
链接编译并执行这个程序, 在图1的对话框中输入图像的文件和选择滤波的类型, 然后点击处理图像按钮, 原彩色图像如图2 (a) 所示, 程序执行后显示的灰度图如图2 (b) 所示。图2 (c) 为加了椒盐噪声的灰度图。图2 (d) 为对图2 (c) 进行线性平滑滤波 (5×5) 后的图像。
3、结论
把MATLAB在数据运算和图像处理方面的优势与VC++强大的界面功能相结合, 这种方式既可以广泛地运用于要求具有友好的操作图形界面和丰富的程序接口中, 又可以运用于需要进行复杂运算求解和图形显示的复杂软件的开发。它减少了开发人员实现算法的困难, 提高系统处理效率及稳定性, 具有很强的实用性。
参考文献
[1]何强, 何英.MATLAB扩展编程[M].北京:清华大学出版社, 2002.
[2]飞思科技产品研发中心.MATLAB 6.5应用接口编程[M], 北京:电子工业出版社, 2003.
[3]刘维.精通MATLAB与C/C++混合程序设计[M], 北京:北京航空航天大学出版社, 2005.
[4]谢佩军, 计时鸣, 张利.VC++与MATLAB混合编程的探讨计算机应用与软件[J], 2006, (2) :128-129.
VC编程 第6篇
MATLAB进行二维、三维图形显示时,程序语法简单,图形精度高,用VC++则需要几十行甚至数百行的程序,但VC++容易做出各种用户界面。在VC++环境下调用MATLAB中的图形显示函数,将二者结合进行编程,则可实现VC++和MATLAB在此功能上的互补及数据共享和数据可视化。
1 编程思路
VC++中调用MATLAB的常用三种方法。
(1)用MATLAB自带的编译器,把M文件翻译成C/C++代码,从而在VC++环境中进行调用,产生脱离MATLAB环境的独立应用程序,但需要MATLAB中的C/C++数学函数库和图形库的支持。图1为利用MATLAB编译器构建C/C++应用程序的过程。其中,阴影方块是用户写的代码,附有阴影的方块是工具软件,无阴影的方块是MATLAB编译器生成的代码,虚线方块是由C/C++编译器产生的目标文件和可执行文件。
(2)图2表示计算引擎应用的情况。
在VC++应用程序中调用MATLAB引擎,功能全面,但不能脱离MATLAB环境,不适于开发[1]。MAT-LAB计算引擎实际上是利用MATLAB提供的一组接口函数(API),在用户开发的语言应用程序中,通过某种通信机制后台调用MATLAB应用程序以完成复杂的系统任务。在Windows平台下,这种通信机制是利用COM应用接口IEngine来完成的。
(3)通过第三方软件MATCOM将M脚本文件和M函数转化为C/C++文件,转化过程简单,支持MATLAB图形功能,但是部分绘图语句无法实现或得不到准确图像,尤其是三维图形。故本文将介绍前两种方法。
2 编程实现
本文中的两个例子是基于Visual C++6.0,MAT-LAB 6.5.1的版本,对其他版本同样适应,均假定matlab安装在目录D:MATLAB6p5下。
2.1 MATLAB编译器
MATLAB随带了编译器,其主要功能是将.m文件翻译成各种源代码,要用到的命令为mcc。mcc的命令行参数很多,设置不同的参数可实现不同的功能。
2.1.1 MATLAB环境配置
编译器使用了CC++库函数,需要使用mbuildsetup和mex-setup对编译器进行配置。这两条命令是自动搜索系统上安装的编译器,然后对所选择的进行核对,Matlab下的环境配置设置一次即可。
2.1.2 mcc编译M文件
编写绘制三维曲面的M函数文件,命名为tripicture.m,程序如下所示:
%已知x,y的最大值与最小值,把x,y各分成50份,即x,y各有51个值
在MATLAB下利用mcc命令将tripicture.m翻译为C/C++代码,并提供图形库支持:
编译后可以得到几个文件,mesh.cppmesh.hpp,parseparams.cpp,parseparams.hpp,tripicture.cpp,tripicture.hpp,tripicture_mainhg.cpp,xlabel.cpp,xlabel.hpp,ylabel.cpp,ylabel.hpp,zlabel.cpp,zlabel.hpp及tripicture.exe和bin目录中的两个fig文件,需要的是.cpp文件及其对应的.hpp文件,bin目录中的两个fig文件。本例中要将所有生成的.cpp、.hpp文件和bin文件夹拷贝到建立的VC++工程中。
2.1.3 VC++环境设置
用MFC App Wizard(exe)建立一个应用程序,点击菜单项Project/Add To Project/Files…将所有拷贝过来的.cpp文件(本例中为tripicture_mainhg.cpp,parseparams.cpp,tripicture.cpp,mesh.cpp,xlabel.cpp,ylablel.cppe及zlabel.cpp)添加到当前工程中。
(1)选择菜单ToolsOptions,在属性页中选择Directories,添加头文件和库文件的搜索路径。
在Show directories for下拉框中选择Include files,添加路径:
再在下拉框中选择Library files,添加路径:
(2)选择菜单ProjectSettings…,选择Link属性页,在Category下拉框中选择Input。
在Object/library modules文本框中加入libmx.lib libeng.lib libmat.lib libmmfile.lib libmatlb.lib libmatpm.lib sgl.lib libmwsglm.lib libmwservices.lib,注意用空格隔开。在下面的Ignore libraries文本框中添加msvcrt.lib。
在属性页中选择C/C++选项,在Category下拉框中选择Code Generation,在Use Run-time Library的下拉列表中选择Debug Multithreaded DLL;同样,Category下拉框中选择Precompiled Headers,并选择Automatic use of precompiled headers,在Through headers编辑框中输入stdafx.h;同样,在C/C++属性页上,Category下拉框中选择General,在Preprocessor definitions编辑框中添加MSVC,IBMPC,MSWIND,用逗号隔开。
2.1.4 VC++中程序说明
把复制到VC++工程下面的所有.hpp文件全部添加为头文件(本例为#include"tripicture.hpp",#include"mesh.hpp",#include"parseparams.hpp",#include"xlabel.hpp",#include"ylabel.hpp",#include"zlabel.hpp")。在程序中用mw Array对MATLAB中调用的参数进行定义并赋值。
实现调用的主要代码如下:
本例中用到的数据minx=-4,maxx=4,miny=-4,maxy=4,所得图形如图3所示:
2.2 MATLAB引擎
从编程复杂度的角度来说,最简单的途径就当属利用MATLAB的引擎功能[2]。与其它各种接口方式相比,引擎所提供的MATLAB功能支持是最全面的。
2.2.1 VC环境设置
用MFC App Wizard(exe)建立一个应用程序,并作如下设置:
(1)通过菜单Tools/Options…,打开设置属性页,进入Directories页面,在目录下拉列表框中选择Include files,添加路径D:MATLAB6p5externinclude再在下拉框中选择Library files,添加路径D:MATLAB6p5externlibwin32microsoftmsvc60
(2)选择菜单Project/Settings…,打开工程设置属性页,进入Link页面,在Object/library modules编辑框中,添加文件名libmx.lib libmat.lib libeng.lib,以空格隔开。
2.2.2 VC++中程序说明
调用命令eng Open打开引擎,然后将mx Array转换成在MATLAB中可操作的形式。具体方法是:在MATLAB中将一个自定义的数据结构复制到mx Array中,后将此矩阵放入MATLAB计算引擎的工作区中,把命令以字符串的形式传递给函数eng Eval String进行执行。使用引擎,计算程序中必须添加头文件#include“engine.h”,程序开始后需要打开引擎,运算完成后要释放内存并关闭引擎。
本例绘制的是一个TIG焊焊接质量神经网络中输出背面熔深(Back Width)与两个输入参数电流(Current)、清洁度(Cleaning)之间的变化曲线。已知两个输入参数的最小值与最大值(minx=80,maxx=100,miny=30,maxy=60),采样个数取为50,即共有51个数。x[51],y[51]中存储了采样后的两个输入变量值,数组matdata[]中存储的是其余参数不变时,电流每变化1次,清洁度变化51次后,神经网络运算出的背面熔深的结果。
主要程序代码部分:
程序运行后得到的图形如图4所示:
3 结论
本文通过两个实例把VC++与MATLAB的数值计算、图形显示功能进行了结合,既保持了VC++的良好用户界面和高执行效率,又保持了MATLAB的优良算法,使VC++和MATLAB各自的优势能够得到充分发挥。当VC与MATLAB互传的参数比较简单或无参数传递时,使用MATLAB编译器实现相对简单方便,且可以脱离MATLAB环境运行,但图形不方便存储;当需要互传大量数据,则使用MATLAB引擎更容易实现,图形方便存储,但不能脱离MATLAB环境。
参考文献
[1]李天昀,葛临东.综述MATLAB与VC++的交互编程[J].计算机仿真,2004,21(9):193-196.
[2]何强,何英.MATLAB扩展编程[M].北京:清华大学出版社,2002.
[3]柏晟.VC++与MATLAB混合编程的方法研究与实现[J].电脑开发与应用,2006,19(4):24-27.
[4]潘爱民,王国印.Visual C++技术内幕[M].北京:清华大学出版社,1998.
[5]飞思科技产品研发中心.MATLAB6.5应用接口编程[M].北京:电子工业出版社,2003.
[6]周灵.基于COM的VC调用Matlab的方法及实现[J].中国科技信息,2006,24:131-133.
[7]张志涌.精通MATLAB 6.5版[M].北京:北京航空航天大学出版社,2003.
VC编程 第7篇
在一个操场的四周摆放着N堆石子, 现要将石子有次序地合并成一堆, 规定每次至少选2堆最多选K堆石子合并成新的一堆, 合并的费用为新的一堆的石子数, 设计算法计算出N堆石子合并成一堆的所需最大总费用和最小总费用。
2 算法设计
2.1贪心算法
贪心算法总是作出在当前看来最好的选择。也就是说贪心算法并不从整体最优考虑, 它所作出的选择只是在某种意义上的局部最优选择。当然, 希望贪心算法得到的最终结果也是整体最优的。虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解。在一些情况下, 即使贪心算法不能得到整体最优解, 其最终结果却是最优解的很好近似。
Huffman提出了构造最优前缀码的贪心算法 , 由此产生的编码方案称为Huffman算法。Huffman编码是广泛用于数据文件压缩的十分有效的编码方法, 其压缩率通常在20%至90%之间, Huffman编码算法使用字符在文件中出现的频率表来建立一个用0,1串表示各字符的最优表示方式。Huffman算法以自底向上的方式构造表示最优前缀码的二叉树T, 算法从C个叶子结点开始, 执行C-1次的合并运算产生最终所要求的树T。
2.2证明Huffman算法的正确性
2.2.1具有贪心选择性质
二叉树T表示字符集C的一个最优前缀码, 证明可以对T作适当修改后得到一棵新的二叉树T”, 在T”中x和y是最深叶子且为兄弟, 同时T”表示的前缀码也是C的最优前缀码。设b和c是二叉树T的最深叶子, 且为兄弟。设f (b) <=f(c), f (x) <=f (y)。由于x和y是C中具有最小频率的两个字符, 有f (x) <=f (b), f (y) <=f (c)。首先, 在树T中交换叶子b和x的位置得到T', 然后再树T' 中交换叶子c和y的位置 ,得到树T''。如图1所示。
由此可知, 树T和T' 的前缀码的平均码长之差为:
因此, T'' 表示的前缀码也是最优前缀码, 且x,y具有相同的码长, 同时, 仅最优一位编码不同。
2.2.2最优子结构性质
二叉树T表示字符集C的一个最优前缀码, x和y是树T中的两个叶子且为兄弟, z是它们的父亲。若将z当作是具有频率f (z) =f (x) +f (y) 的字符, 则树T’ =T- {x,y} 表示字符集C’ =C- {x, y} ∪ { z} 的一个最优前缀码。因此, 有:
1)
2)
如果T’不是C’的最优前缀码, 假定T”是C’的最优前缀码, 那么有,
显然T’”是比T更优的前缀码, 跟前提矛盾, 所以T' 所表示的C' 的前缀码是最优的。
由贪心选择性质和最优子结构性质可以推出哈夫曼算法是正确的, 即Huffman树产生的一棵最优前缀编码树。针对石子合并问题也可以采用贪心策略, 每次选最小的K个元素进行合并, 与二元Huffman算法类似, 同样可以证明其满足贪心选择性质和最优子结构性质。
3 算法实现
程序开发中, 采用了QT实现界面, VC++实现算法。用到了信号和槽的机制, 利用了链表这种数据结构, 在界面上使用了button控件、label控件、lineedit等控件。下面给出初始化窗口代码和两个重要的核心事件代码, void Main Window::on_push Button_2_clicked(), 用于将输入到文本框中的字符串所包含的数字提取出来, 主要根据石堆数, 分割出每堆石子的个数; void Main Window::on_push Button_5_clicked(), 此函数为算法的核心功能, 实现利用构建多元Huffman树, 计算出石子合并所需最大总费用, 所需最小费用类似。
4 运行结果
程序调试通过, 运行结果如图2 (a) , 2 (b) , 2 (c) 所示。
(c)计算石子合并的最小费用
5 结语
基于VC的数据库编程设计与实现 第8篇
1 VC数据库编程的特点
对于例如Access,Oracle,FoxPro和DBase IV这些产品都是完全把数据库管理作为核心的,这类产品的最大优点就是善于帮助编程者创建商业数据库管理器。编程人员在应用这类数据库时,就可以使用Delphi和Visual Basic等环境来协助实现构建这类管理器。事实上使用这类软件之后会感觉非常简单和方便,数据库的管理系统DBMS具备成熟的编写、良好的用户界面以及高速的搜索能力。所以如果从方便简单的角度来看,Delphi和VisualBasic这类的RAD环境应该更适合在数据库的开发中,使用这类软件能够大大简化程序的设计工作。
虽然对于多数的数据库应用来讲,选择使用VC++也许并不是最合适的。但同时也应该考虑到,单一的数据库管理应该要与其他的一些功能相结合才能更多地发挥作用,而一般的数据库软件并不轻易支持那些拓展功能。此时,为了应用各种复杂功能,Visual C++便能够为编程人员提供的那些重要的东西。由于VC能对底层提供强大的支持,本身高效率的代码结构作用下,编写出的数据库有关的应用程序就能有规模小、实现底层访问并且可以提供实时访问的优点。例如在编写数据库的实用程序和驱动程序时,就适合选择Visual C++来实现更方便的设计环境,又例如遇到对内存有限制或是硬盘较小的时候,Visual C++语言便能为编程人员提供无限无价的工具。
2 VC数据库编程设计与实例
2.1 ODBC方式
Microsoft最开始是以开放数据库的互连(ODBC)为宗旨的,ODBC属于一种Microsoft引进的早期数据库的接口技术,也是ADO的前身技术。Microsoft之所以会引进这个技术,其中一个最重要的原因就是它能用非语言的专用方式为程序员提供一种访问数据库内容时更为便捷的方法。也能使编程者访问DBF文件或者Access Basic获得MDB文件里的数据信息时,不需要掌握Xbase程序的专业设计语言。ODBC工作的方式和Windows类似,它是通过包含在DLL中的驱动程序来完成任务的。ODBC提供了一套两个驱动程序,一种提供数据库管理器的专业语言,另一种提供程序设计语言的公用接口。这两种驱动程序的结合点在于允许Visual C++通过标准函数来调用经过公用接口访问的数据库内容。当然,也包含其他与ODBC相关的实用程序设计类型的DLL,它就获得了管理ODBC数据源的许可。
Visual C++中的MPC类库为一些数据库类做了定义。在运用ODBC进行编程时,设计者会经常用到CRecordView(可视记录集类),CRecordSet(记录集类)以及CDatabase(数据库类)。其中的CRccordSet类对象能够提供从数据源里获得的记录集。而CRecordView类对象可以通过控制的方式显示出数据库的记录。该视图可以实现与一个CRecordSet对象中的表视图进行直接连接。CDatabase类对象主要提供连接数据源通道,通过它编程人员能够对数据源直接实施操作。
2.1.1 数据链接
CRecordSet类中实现了定义一种成员变量m_pDatabase:Cdatabasc*m_pDatabase,这是能够指向对象数据库类的一个指针。若是在CRecordSet类的对象调用到Open()函数以前,把一个已经成功打开的CDatabase类对象指针信息传送至m_pDatabase,便能实现共享一样的CDatabase类对象。
2.1.2 查询记录
OBDC的查询记录通常使用的是CRecordSa::Open()以及CRecordSet::Requery()成员函数。运用CRecordSet类对象以前,还应该先使CRecordSa::Open()函数去取得有效记录集。当已经成功使用了CRecordSa::Open()函数后,再去用查询操作时,便能够应用到CRecordSet::Requefy()函数了。值得注意的是,编程人员在调用到CRecordSet::Open()函数的过程中,若是已经把一个完全打开的CDatabase对象指针发至CRecordSet类对象中的m_pDatabase成员变量,则必须运用此数据库对象来建立一个ODBC的连接;或者是当m p Database是空指针时,马上新建一个CDatabase类对象,同时还要让它连接到缺省数据源中,然后再对CReccrdSet类对象进行初始化操作。缺省的数据源可以通过GetDefaultConnect()函数来获取。
若是没有发现指定的参数,程序就只能运用程序中缺省的SQL语句,即对GetDefaultSQL0函数里所指定的SQL语句来进行操作。
2.2 ADO方式
理解ADO方式之前需要先了解一下OLE—DB的知识。OLE—DB顾名思义就是用OLE(更具体地说,就是部件的对象模型COM)作为数据访问所提供的一套接口。与其他任何的COM对象相同,都能够实现查询、创建或是撤销OLE—DB的一个对象。称OLE—DB的对象来源为提供者。各类OLE—DB提供者属于Visual C++软件包的其中一部分,当然也可能是在厂商进行升级相关数据库的产品时提供的。OLE—DB的优点在于,同一提供者能够与任何的一个Visual Studio产品合作:例如Visual J++,Visual InterDev,Visual Basic和Visual C++。OLE—DB还会依赖事件,这一点也与任何一个COM对象相同。这些事件能主动说明什么时候会要求更新数据库表,来显示其他编程中所生成的新项数据,或是其请求的表会在什么时候准备完全,以备用户查看。当然还会出现这样的事件过程,它们能用作发送信号作为通知各类数据库出现的错误,或是其他要求立刻轮询的活动。
ADO既可以应用VC所具备的强大功能,且使用起来更为方便,下面将以ADO模式数据库的访问为例,来展示在VC环境下怎样进行数据库的应用。以下是使用ADO编程的具体方法。
(1)应用预处理指令#import
程序员在编译程序过程中,会遇到VC++读出msadol5.dll所含的类型库信息,然后自动产生2个此类型库里的头文件以及实现文件msadol5.tlh与msadol5.tli(在用户的Debug或是Release目录里)。这两个文件中已经定义了ADO所有的方法和对象,还有部分枚举型常量等等。这里的程序只需要直接对这些方法进行调用就可以了,这就和使用MFC里的COleDispatDriver类调用到Automation对象过程十分相似。
(2)使用MFC里的CIDispatchDriver也是利用读取msadol5.dll里包含的类型库信息,再建立起一个与COleDispatchDriver类相关的派生类,接下来再通过它去调用ADO对象。
(3)直接用COM提供的AP可以使用以下的代码:
以上的3种编程方法中,第一种与第二种比较类似,但笔者认为第一种更为好用一些,而第三种方法可能是最麻烦的。不过第三种可能在效率上也是最高的一种编程法,也具有最小的程序尺寸,且对ADO有最强大的控制能力。如果编程人员需要一种绕过ADO来直接调用OLEDB底层的编程法时,推荐要应用第三种编程。使用ADO编程关键就在于能够熟练掌握ADO所提供的各类方法(mahod)、对象(object)、容器(collection)以及属性(property)。
3 结语
在数据库编程的设计中,VC是一个非常强大的工具。而ADO是Microsoft数据库中的应用程序所开发的一个新接口。它是建立在OLE/DB上的一种高层数据库访问技术。在VC之下应用ADO方式来进行数据库的编程设计既能利用VC的优良特性,更能为编程人员提供便捷,这是一套值得向大家推荐的方法。
摘要:VC适合各类编程人员的需求,ODBC方式和ADO方式是VC的主要两种编程模式。分析了VC数据库编程的特点,比较了VC环境之下的两种主要的数据库开发模式,并给出了详细的ADO模式编程的具体实例。
关键词:数据库,VC,ODBC模式,ADO模式
参考文献
[1]谢厚亮,刘伟跃.VC的数据库应用[J].电脑知识与技术,2009,(05).
[2]廖远来.数据库编程接口及其VC++应用程序设计[J].电脑与电信,2007,(05).
[3]蔡长安.VC++6.0环境下的ODBC数据库接口与编程技术[J].江汉大学学报(自然科学版),2003,(01).
VC编程 第9篇
VC++是强大的windows应用程序开发工具,它提供了高度集成的工具集和可视化集成的编程环境,包括了Microsoft的代码优化技术,极大提高了应用程序的设计效率,还提供了复杂的资源编辑器,拥有强大的GUI功能[2]。
因此,实现MATLAB与VC++等可视化程序设计语言的混合编程,提高程序的执行速度,美化应用程序界面,脱离MATLAB环境,发布独立的应用程序,同时利用MATLAB在数值分析、矩阵计算、信号处理和图形显示等方面的强大功能,具有重要的意义。
1 MATLAB与VC++混合编程方法
MATLAB与VC++有多种接口方法,但是一些常见方法难以实现,执行效率低,如MATLAB Engine、直接调用MATLAB的C/C++数学函数库等。该文介绍三种只要在VC++平台下调用,不需要编写大量语句,更加适用于实际应用和软件开发的接口方法:利用MATLAB自带编译器MCC;使用MATCOM软件转换M文件;以及利用COM Builder工具制作COM组件。
1.1 利用MATLAB自带编译器MCC
MCC是MATLAB自带的优化编译器,作用是将m文件转化成C/C++代码,通过MCC,可以将MATLAB数学库、图形库和界面的MATLAB程序转化为DLL动态链接库、C/C++文件、EXE应用程序等一系列文件。MCC实现MATLAB与VC++混合编程的步骤为[3,4]。
1)编写M文件;
2)配置MATLAB编译器,并用MCC编译M文件;
3)创建VC++工程;
4)使用由MCC编译成的cpp文件。
下面通过绘制正弦函数图形的程序,具体应用MCC编译器方法来实现MATLAB与VC++的混合编程。
1)在MATLAB下编写sinewave.m文件并保存,程序如下:
2)配置MATLAB编译器,并编译M文件
首先,用“mbuild-setup”将MATLAB编译器设置为VC++6.0;
然后,在MATLAB命令窗口编译M文件,输入:
其中,操作参数–B csharelib是一个绑定操作,-v显示编译信息。在编译信息中可确定VC++包含的文件路径和链接库路径的配置。
3)创建VC++工程,MCC。
在VC++下生成一个基于对话框的工程,并为该对话框添加一个按钮。
4)配置VC++环境。
在VC++的菜单Tools中选择Directories,为Include files、Library files添加“%MATLAB7%externincude”。在Project中选择Settings,为Link添加“mclmcrrt.lib,libsin.lib”。在MATLAB目录下,将MCC编译“sinewave.m”生成的libsin.h,libsin.dll,libsin.ctf和mclmcrrt.lib文件复制到MCC工程目录下。并用Project中的add to project将libsin.h加入工程中。
5)编辑主程序。
在对话框程序MCCDlg.h中添加头文件#include“libsin.h”和“mclmcr.h”,并在On Init Dialog()函数中添加如下代码,用于初始化libsin.dll进程:
在按钮的响应函数中,添加mlf Sinewave(),实现对M文件的调用。编译执行后,可通过点击对话框上的按钮,调用M文件,进行正弦图像的绘制,完成MATLAB与VC++的混合编程。
1.2 使用MATCOM转换M文件
MATCOM是Mathworks公司推出的由MATLAB到C++的编译开发软件平台。MATCOM可以把M文件翻译成C++源文件,并编译为脱离MATLAB环境可独立运行的程序。它的编译环境为MIDEVA。通过MATCOM链接MATLAB的M文件有以下三种方式:
1)将M文件直接转换为C/C++,然后添加至MSVC工程中;
2)利用MATCOM生成独立执行的EXE文件,但由于VC和MATLAB之间不能交互,通用性差,仅适用于在VC中调用MATLAB实现图形显示。
3)实现在Visual C++6.0环境中直接对M文件进行编译,这种方法通过使用Visual MATCOM工具条,在脱离了MATLAB环境条件下,实现了VC++对M文件的调用,大大方便了应用程序的开发。
本文采用第三种—利用MATCOM直接在VC++中对M文件进行编译的方式,实现上述绘制正弦函数图形的程序[5]。
1)安装MATCOM4.5,然后在VC++中设置MATCOM的调用环境,并生成一个Visual MATCOM工具条。
安装MATCOM4.5后,复制%MATCOM4.5%binusertype.dat文件到%VC++%Commonmsdev98Bin下。在VC++中,选择Tools->Customize->Add-instand and macrofiles,选择Browse,选定%MATCOM45%binmvcide.dll文件。然后,可在VC++环境中,看到Visual MATCOM工具条。
2)创建VC++工程,MATCOM。
在VC++下生成一个基于对话框的工程MATCOM,并为该对话框添加一个按钮。
3)转换sinewave.m文件。
单击Visual MATCOM工具条上的m++,将保存过的MATLAB文件sinewave.m进行转换。可看到在File View中多了sinewave.m、sinewave.cpp、v4501v.lib、sinewave.h等文件,表示转换成功。sinewave.h添加的程序如下:
4)在VC++工程中调用转换后的函数sinewave.h,编辑主程序。
在主程序中添加头文件:#include“matlib.h”,#include“sinewave.h”,并为按钮On BUTTON()函数中添加如下代码:
编译执行后,可通过点击对话框上的按钮,利用MATCOM方式,进行正弦图像的绘制,完成MATLAB与VC++的混合编程。
1.3 利用COM Builder工具制作COM组件
组件对象模型(COM,Component Object Model)是一系列面向对象技术和工具的集合。使用COM,用户可以选择不同厂商提供的组件并将它们集成到一个完整的应用程序中去。MATLAB COM Builder,可以将MATLAB开发的算法做成COM组件,并被VC++、VB等支持COM的语言所引用。该文就利用COM组件的方式,继续实现绘制正弦函数图形的程序[6]。
1)创建COM组件。
在MATLAB命令窗口输入comtool,出现COM Builder工具,在该生成器中,创建新的工程component和sinewave类,并添加sinewave.m文件,点击Build→COM Object,生成COM组件。
2)创建VC++工程,COM。
在VC++下生成一个基于对话框的工程COM,并为该对话框添加一个按钮。
3)VC++中调用COM组件。
将component_idl.h、component_idl_i.c和mwcomtypes.h文件拷贝到工程COM目录下。选择Projece→Settings-〉Files,添加上述三个文件,并为程序添加三个头文件:#include“component_idl.h”,#include“component_idl_i.c”和#include“mwcomtypes.h”。为按钮On BUTTON()函数添加如下代码:
编译执行后,可通过点击对话框上的按钮,利用COM组件的方法,进行正弦图像的绘制,完成MATLAB与VC++的混合编程。
2 结束语
通过上述三种方法的分析和实例应用,可以发现上述三种方式都不需要在VC++平台下编写大量语句,将程序的处理部分,全部用M文件完成,VC++中只需要简单的调用即可,相对于其他的混合编程方法,如通过MATLAB Engine、直接调用MATLAB的C/C++数学函数库等执行效率低、需要用户在VC++下大量编写代码的方式,有着显著的优点,更加适用于实际应用和软件开发。这三种MATLAB与VC++的混合编程方法又有各自的特点:
1)利用MATLAB自带编译器MCC,将M文件转换成C/C++文件,除了上述优点外仍有很多限制,如:不能转换脚本M文件,只能转换M函数;不能使用MATLAB对象;不能用input或者eval操作MATLAB空间变量;不能动态地命名变量,然后用load或者save命令来操作;不能处理具有嵌套调用其他M文件的M文件;不能使用MATLAB内联函数等。
2)使用MATCOM转换M文件,相比其它两种方法,它具有转换过程简单,容易实现;不仅可以转换独立的脚本文件,也可以转换嵌套脚本文件;设置环境后,可以使用Matlab的部分工具箱函数等优点。但是,它仍旧存在以下不足:第一,需要安装MATCOM,为程序的开发增加了依赖性;第二,对struct等类的支持有缺陷,对class数据类型、部分绘图语句无法实现或得不到准确图象,尤其是三维图象;第三,利用MATCOM方式,在VC++编译过程中,程序很可能会发生不正常运行。
3)利用COM Builder工具制作COM组件,这种方法增强了对图形的支持和程序的通用性,具有较高的运行效率,但是不支持脚本文件。因此在程序较大、调用工具箱函数或调用函数较多时推荐使用。
MATLAB与VC++的混合编程技术,既充分满足了对数值分析、矩阵运算和图形显示的要求,又降低了软件开发的难度,提高了系统的执行速率。但根据使用情况的不同,应选择不同的混合编程方法。
参考文献
[1]Duane,Bruce.精通MATLAB7[M].朱仁峰,译.北京:清华大学出版社,2010.
[2]魏朗,陈涛.Visual C++程序设计攻略教程[M].西安:西安电子科技大学出版社,2008.
[3]苏金明,刘宏,刘波.MATLAB高级编程[M].北京:电子工业出版社:2005,215-228.
[4]Math Works.Matlab complier userguide:version2[M].New Mexico:MathWorks,1998.
[5]牟彧清,王汝霖,李国新.MATLAB与VC接口技术的研究[J].微计算机信息,2006,22(7-3):275-277.