logo资料库

matlab与C++实现.pdf

第1页 / 共5页
第2页 / 共5页
第3页 / 共5页
第4页 / 共5页
第5页 / 共5页
资料共5页,全文预览结束
潘大夫,汪渤,周志强:Matlab 与 C/C++混合编程技术研究 计算机工程与设计 Computer Engineering and Design 2009,30 (2) 465 计算机应用 Matlab 与 C/C++混合编程技术研究 潘大夫, 汪 渤, 周志强 (北京理工大学 信息科学技术学院自动控制系,北京 100081) 摘 要:Matlab 具有强 大的数值计算 和分析等能力,而 C/C++是 目前最为流行的 高级程序设计 语言,两者 互补结合的混 合编 程在 科学研究和工程 实践中具有非 常重要的意义。因此,从 Matlab 调用 C/C++代码及 C/C++ 调用 m 文件 两方面,深入地 研究 了它 们之间混合编程 的原理和实现 机制,并且给出了具 体条件下的混合 编程方法和步 骤。实例表明,提出 的 Matlab 与 C/C+ + 混合编程方法是 简洁、有效的。 关键 词:Matlab; C/C++; 混合 编程; 计算引 擎; MEX; DLL 中图 法分类号:TP391 文章编号:1000-7024 (2009) 02-0465-04 文献标 识码:A Research on mixed programming technology of Matlab and C/C++ (Department of Automatic Control, School of Information Science and Technology, Beijing Institute of Technology, PAN Da-fu, WANG Bo, ZHOU Zhi-qiang Beijng 100081, China) Abstract:Matlab has strong ability of numerical value calculation and analysis, whereas C/C++ is one of the most popular programming languages. And the mixed programming of Matlab and C/C++ is significant in scientific research and engineering applications. Therefore, the mechanism of Matlab inducing C/C++ codes and C/C++ calling m file are proposed separately. The mixed programming methods and approaches in different conditions are also presented. At last, the validity of the mixed programming between Matlab and C/C++ is testified with some examples. Key words:Matlab; C/C++; mixed programming; compution engineer; MEX; DLL1 0 引 言 1 配置 Matlab 编译环境 Matlab 是当前应用最为广泛的数学软件,具有非常强大 的数值计算、数据分析处理、系统分析、图形显示甚至符号运 算等功能 [1]。它为用户提供了一种比其它工具更为简洁、自 由、可移值性好的编程环境。利用这一完整的数学平台,用户 可以快速实现十分复杂的功能,极大地提高工程分析计算的 效率[2-3]。但与其它高级程序[4]相比,Matlab 程序是一种解释执 行程序,不用编译等预处理,因此Matlab 程序运行速度较慢[1]。 C/C++语言是目前最为流行的高级程序设计语言之一[4-5]。 它可对操作系统和应用程序以及硬件进行直接操作,C/C++语 言明显优于其它解释型高级语言,一些大型应用软件如Matlab 就是用 C 语言开发的。在工程实践中,用户有时需要在 Matlab 环境中调用已编写的 C/C++代码,有时需要在 C/C++中调用 Matlab 编写的数值处理、矩阵运算等代码,这就产生了 Matlab 和 C/C++混合编程的问题。因此,本文基于常用的 Matlab6.5 和 VC6.0 开发环境,在 Windows 平台下就它们之间的混合编 程问题从 Matlab 调用 C/C++和 C/C++调用 Matlab 两方面进行 深入研究并举例说明。 在 Matlab 与 C/C++混合编程之前,必须先对 Matlab 的编 译应用程序 mex 和编译器 mbuild 进行正确的设置[1]: 对 Matlab 编译应用程序 mex 的设置: Mex -setup 然后按系统提示进行选择。 对 Matlab 编译器 mbuild 的设置: Mbuild -setup 同样,按后面提示选择即可。 2 Matlab 调用 C/C++ Matlab 调用 C/C++的方式主要有两种:利用 MEX 技术和 调用 C/C++动态连接库。 2.1 调 用 C/C++ 的 MEX 文 件 MEX 是 Matlab Executable 的缩写,它是一种“可在 Matlab 中调用的 C(或 Fortran)语言衍生程序”[6]。即 MEX 文件的源码 是由 C 或 Fortran 语言编写的;后经 Matlab 编译器处理而生成 的二进制文件;它是可以被 Matlab 解释器自动装载并执行的 E-mail:pandaful@bit.edu.cn 收稿日期:2008-01-13 基金项目:国家部委预研基金项目 (51405030104BQ0171)。 作者简介:潘大夫 (1980-),男,陕西汉中人,博士研究生,研究方向为目标识别与跟踪; 汪渤,博士,教授,研究方向为精确制导技术;周 志强,博士研究生,研究方向为地面目标识别与跟踪。
466 2009,30 (2) 计算机工程与设计 Computer Engineering and Design 动态连接程序。MEX 文件的使用极为方便,其调用方式与 Matlab 的内建函数完全相同,只需在 Matlab 命令提示符下键 入 MEX 文件名即可。因此,对于大量现有的 C/C++代码可无 须改写成 Matlab 专用的 m 文件而在 Matlab 中执行;对于那些 Matlab 运算速度过慢的算法,可以调用 C 语言编写的相应代 码,从而提高效率。 要实现 C/C++文件到 MEX 文件转换,必须在 Matlab 编译 应用程序 mex 的设置中选择 VC 编译器。一个 C/C++的 MEX 源程序通常包括 4 个组成部分,其中前 3 个是必须包含的内 容,第 4 个则根据所实现的功能灵活选用: (1)#include“mex.h”; (2) MEX 文件的入口函数 mexFunction,MEX 文件导出名 必须为 mexFunction 函数; (3)mxArray; (4)API 函数。 下面通过一个简单的例子说明 C/C++的 MEX 源程序编 写和调用过程: #include "mex.h" void timestwo(double y[], double x[]) { y[0] = 2.0*x[0]; } /*下面这个 mexFunction 的目的是使 Matlab 知道如何调 用这个 timestwo 函数*/ } 用指令 mex timestwo.c 编译此文件,然后在 Matlab 命令行 下调用生成的 MEX 文件: >>x = 2; >>y = timestwo(x) >>y = 4 现在常用的 C 语言编译器也能够编译 C++程序,使用这 些编译器,通过 mex 命令就可实现 C++语言的 MEX 文件。和 C 语言 MEX 一样,C++语言 MEX 文件也必须实现和导出 MEX 文件入口函数。在这两种语言的 MEX 文件中,mexFunction 的 定义是完全一样的,只是在 C++函数体内可以使用或调用其 它 C++语言函数。 在 Matlab 上运行 MEX 不需要任何工具箱。使用 MEX 文 件的优点是代码重用、速度提升经及功能扩展。 2.2 调 用 C/C++ 动 态 连接 库 从 Matlab6.5(R13)起,Matlab 提供了对动态连接库 DLL 文 件的接口[7]。利用这个接口,可以在 Matlab 中调用动态连接库 所导出的函数。Matlab 对 DLL 的接口支持以各种编程语言编 写的 DLL 文件。在调用 DLL 文件中的功能之前,需要准备包 含函数定义的 C 语言头文件。对于 C/C++语言开发的 DLL 文 件,可使用源程序中相应的头文件;而对于用其它语言开发的 DLL,则需要手工准备等效的 C 语言函数定义头文件。 在Matlab 中利用动态连接库接口技术通常需要完成以下 void mexFunction (int nlhs, mxArray *plhs [],int nrhs, const 4 个步骤: mxArray *prhs[]) /* nlhs 是 Matlab 命令行方式下输出参数的个数;plhs[]是 输出参数;nrhs 是输入参数的个数;prhs[]是的输入参数;*/ { double *x,*y; int mrows,ncols; if(nrhs!= 1) { mexErrMsgTxt("One input required."); } else if(nlhs>1) { mexErrMsgTxt("Too many output arguments"); } mrows = mxGetM(prhs[0]); ncols = mxGetN(prhs[0]); if(! mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || !(mrows == 1 && ncols == 1)) { mexErrMsgTxt("Input must be a noncomplex scalar double."); } plhs[0] = mxCreateDoubleMatrix(mrows,ncols,mxREAL); x = mxGetPr(prhs[0]); y = mxGetPr(plhs[0]); timestwo(y,x); (1)打开动态连接库文件; (2)为调用函数准备数据; (3)调用动态连接库文件中导出的函数; (4)关闭动态连接库文件。 为了完成以上步骤,常用到的 Matlab 函数有:loadlibrary, loadlibrary,calllib,libfunctions,lipointer,libstruct,libisloaded。 下面通过例子说明 Matlab 调用 C/C++ 动态连接库的方法和步骤: (1)在 VC 环境下,新建工程->win32 动态连接库->工程名 Test1->empty 工程->完成。 (2)新建->C++源文件->添加 a.cpp,内容如下: #include "a.h" _declspec(dllexport) int add(int a, int b) { return a+b; } (3)新建->C/C++头文件->添加 a.h,内容如下: _declspec(dllexport) int add(int a,int b); 然后编译生成 Test1.dll 动态连接库文件,将 Test1.dll 和 a.h 拷贝到 Matlab 工作目录下。 (4)在 Matlab 命令行下,调用 Test.dll: >>loadlibrary(‘Test1’,’a.h’); >>x = 7; >>y = 8; >>calllib(‘Test1’,‘add’,x,y)
潘大夫,汪渤,周志强:Matlab 与 C/C++混合编程技术研究 2009,30 (2) 467 Ans = 15 >>unloadlibrary(‘Test1’) 调用 DLL 动态连接库的方法,为 Matlab 重用科研实践中 积累的大量实用 C/C++代码提供了一种简洁方便的方法。与 调用 MEX 文件相比,该方法更加简便实用。 3 C/C++调用 Matlab 在工程实践中,C/C++调用Matlab 的方法主要有调用 Mat- lab 计算引擎、包含 m 文件转换的 C/C++文件,以及调用 m 文 件生成的 DLL 文件。 3.1 利 用 Matlab 计 算 引 擎 Matlab 的引擎库为用户提供了一些接口函数[7-8],利用这些 接口函数,用户可在自己的程序中以计算引擎方式调用 Matlab 文件。该方法采用客户机/服务器的计算方式,利用 Matlab 引 擎将 Matlab 和 C/C++联系起来。在实际应用中,C/C++程序为 客户机,Matlab 作为本地服务器。C/C++程序向 Matlab 计算引 擎传递命令和数据信息,并从 Matlab 计算引擎接收数据信息。 Matlab 提供了以下几个 C 语言计算引擎访问函数供用户 使用 [2,8]:engOpen,engClose,engGetVariable,engPutVariable,eng- EvalString,engOutputBuffer,engOpenSingleUse,engGetVisible, engSetVisible。 下面以 C 语言编写的调用 Matlab 引擎计算方程 3 2 + 5 = 0根的源程序 example2.c 为例,说明 C/C++调用 Matlab 计算 引擎编程的原理和步骤: #include #include #include #include "engine.h" int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInstance,LPSTR lpszCmdLine, int nCmdShow) { Engine *ep; mxArray *P = NULL,*r = NULL; char buffer[301]; double poly[4] = {1,0,-2,5}; if (!(ep = engOpen(NULL))) { fprintf(stderr,"\nCan't start MATLAB engine\n"); return EXIT_FAILURE;} P = mxCreateDoubleMatrix(1,4,mxREAL); mxSetClassName(P,"p"); memcpy((char *)mxGetPr(P),(char *)poly, 4*sizeof(double)); engPutVariable(ep,P); engOutputBuffer(ep,buffer,300); engEvalString(ep,"disp(['多项式',poly2str(p,'x'),' 的根']), r = roots(p)"); MessageBox(NULL,buffer,"example2 展示 MATLAB 引 擎的应用",MB_OK); engClose(ep); mxDestroyArray(P); return EXIT_SUCCESS; } 在 Matlab 下运行 example2.exe: mex -f example2.c exmaple2.exe 的运行结果如图 1 所示。 图 1 exmaple2.exe 运行结果 以上是用 Matlab 自带的编译应用程序 mex 对 Example2.c 编译的。C/C++源程序也可在当前流行的 VC 开发环境下编 译:将 libeng.lib 和 libmx.lib 两个静态链接库加入当前工程,选 择 Project 菜单的 Settings 项,在“link/object/library modules”中 填入两个静态链接库的完整目录即可。 利用计算引擎调用 Matlab 的特点是:节省大量的系统资 源,应用程序整体性能较好,但不能脱离 Matlab 的环境运行, 且运行速度较慢,但在一些特别的应用(例如需要进行三维图 形显示)时可考虑使用。 3.2 利 用 mcc 编 译 器 生 成的 cpp 和 hpp 文件 从 Matlab 的 5.1 版本开始,Matlab 提供了自带的 C++Com- plier--mcc,该编译器能够将 Matlab 的 m 文件转换为 C/C++代 码[1]。因此,它为 C/C++程序调用 m 文件提供了另一种便捷的 方法。下面举例说明相应步骤: (1)建 m 文件 example3.m,内容为: function y = exmaple3(n) y = 0; for i = 1:n y = y+i; end 保存后在命令窗口中输入: (格式:mcc-t-L Cpp-h 文件名) mcc-t-L Cpp-h example3 然后会在工作目录下生成 example3.cpp 和 example3.hpp 两个文件。 (2)在 VC 中新建一个基于对话框的 MFC 应用程序 Test2, 添加 Test 按钮及响应函数,函数内容见 e 步。将上面生成的 两个文件拷贝到 Test2 工程目录下。 (3) 在 VC 中选择:工程->设置,选择属性表 Link 选项,下 拉菜单中选择 Input,在对象/库模块中加入 libmmfile.lib libma- tlb.lib libmx.lib libmat.lib libmatpm.lib sgl.lib libmwsglm.lib lib- mwservices.lib,注意用空格将它们格开;而在忽略库中加入 msvcrt.lib;然后选择属性表 C/C++选项,下拉菜单选 General, 在 预 处 理 程 序 定 义 中 保 留 原 来 有 的 内 容, 并 添 加 MSVC, IBMPC,MSWIND,并用逗号将它们隔开。再选择下拉菜单的 Precompiled Headers 选项,在“自动使用预补偿页眉”中添加 stdafx.h,然后确定。 (4)选择:工具->选项,属性页选择“目录”,在 include files
468 2009,30 (2) 计算机工程与设计 Computer Engineering and Design 里面加入: mcc-t-W libhg: example4-T link: lib-h libmmfile.mlib lib- C:\MATLAB6p5p1\extern\include, C:\MATLAB6p5p1\extern\include\cpp; 然后在 Library files 里面加入: C:\MATLAB6p5p1\bin\win32, C:\MATLAB6p5p1\extern\lib\win32\microsoft\msvc60;注意 根据用户的 Matlab 安装位置,修改相应目录。 mwsglm.mlib example4 然 后 在 工 作 目 录 下 会 生 成 example4.dll,example4.lib, example4.h 共 3 个文件。 (2) 在 VC 中新建一基于对话框的应用程序 Test3,然后添 加 Test 按钮及响应函数,函数内容见 d 步,再将生成的 3 个文 件拷贝到 Test3 工程目录下。 (5)在 Test 按钮响应函数所在文件中添加如下的头文件: ...... #include "matlab.hpp" #include "example3.hpp" ...... Test 函数响应代码为: int i; mwArray n; n = 10; n = example3(n); i = n.ExtractScalar(1); CString str; str.Format("example3 的返回值是:%d",i); AfxMessageBox(str); (6)编译,连接,执行,结果如图 2 所示。 (3)VC 编译环境的设置如同(3)、(4)步; (4)在 Test 按钮响应函数所在文件中添加如下的头文件: ...... #include "example4.h" ..... Test 函数响应代码为: mxArray* para = mxCreateDoubleScalar(2); mxArray* result; example4Initialize(); result = mlfExample4(para); CString str; str.Format("%f",mxGetScalar(result)); AfxMessageBox(str); (5)编译,连接,执行,结果如图 3 所示。 图 2 Test2 运行结果 注意:如果用户程序中用到其它函数,Matlab 将为每个函 数生成对应的 hpp 和 cpp 文件,必须将它们拷贝到工程目录下。 此方法虽能将 m 文件转化为 C/C++代码,然后包含到 C/ C++程序中。但是每次都需要把 Matlab 生成的一大堆 cpp 和 hpp 文件拷到 C/C++工程中,这是很不方便的。 3.3 利 用 mcc 编 译 器 生 成的 的 DLL 文 件 Matlab 自带的 C++ Complier 不仅能够将 Matlab 的 m 文件 转换为 C/C++的源代码,还能产生完全脱离 Matlab 运行环境 的独立可执行 DLL 程序。从而可以在 C/C++程序中,通过调 用 DLL 实现对 Matlab 代码的调用。下面,通过一个简单的例 子说明 C/C++调用 m 文件生成的 DLL: (1)建立 m 文件 example4.m: function result = example4(para) x = [1 para 3]; y = [1 3 1]; plot(x,y); result = para*2; 然后在命令窗口中输入: (格式:mcc-t-W libhg:<生成的 dll 文件名> -T link:lib-h libmmfile.mlib libmwsglm.mlib 文件名) 图 3 Test3 运行结果 利用 mcc 编译器生成的 DLL 动态连接库文件,只需在 C/ C++编译环境中将其包含进来,调用导出函数即可实现原 m 文件的功能,极大地方便了用户的代码设计。 4 结束语 本文从 Matlab 调用 C/C++代码和 C/C+调用 m 文件两方 面,详细研究了 Matlab 与 C/C++混合编程技术。对于 Matlab 调用 C/C++代码,给出了常用的 MEX 技术和调用 C/C++动态 连接库的方法,并对它们进行比较。针对实际中经常遇到的 C/C++调用 Matlab 问题,通过研究给出了常用的 3 种方法及其 特点:利用 Matlab 计算引擎的方法,由于混合编程后的可执行 程序脱离不了 Matlab 的运行环境,运行速度很慢;利用 mcc 编 译器将 m 文件转化为 C/C++文件的方法,虽能独立于 Matlab 运 行环境,但在C/C++环境中包含生成的文件非常繁琐;然而,调 用 m 文件生成的 DLL 为用户提供了一种简洁有效的方法。除 了 Matlab 自带的 mcc 外,Matcom 也能将 m 文件编译为 C/C++ 文件和 DLL 文件[2,6],但混合编程原理一样,在此省略。 (下转封三)
徐红艳,冯勇:基于 Agent 集成学习情境的 E_Learning 系统设计与实现 2009,30 (2) 521 信息,知识资源 Agent 承担了知识抽取工作,服务器支出较少。 并且个人需求的处理也已在系统构建时完成,这极大地减少 了在线处理量;最终使用 CAIS 学习的学生在学习效率 (人均 完成课程所需上机时间)和学习效果(考试通过率)方面都得到 了显著的提升。对比的结果反映出依据本文所给设计实现的 基于 Agent 集成学习情境的 E_Learning 系统具有良好的系统 性能,有利于提高用户的学习效率。 表 4 传统 E_Learning 系统与 CAIS 应用效果的对比 指标 传统 E_Learning 系统 CAIS 初始用户界面生成速度/秒 用户界面更新速度/秒 平均服务器资源占用率/% 平均服务器输出流量/(兆字节/次) 人均完成课程所需上机时间/学时 考试通过率/% 2.378 0.756 78.6 786 35.6 77.8 1.575 0.324 35.7 58 32.7 94.4 5 结束语 当今时代,需要 E_Learning 系统适应人和知识资源分布 广泛的特征,并注重对用户个性化需求的满足。本文在分析 新需求的基础上,对 E_Learning 系统进行设计,提出了基于 Agent 集成学习情境的 E_Learning 系统框架,给出了系统关键 组件的实现方法,最后对系统加以实现,并分析了系统的应用 效果。通过应用效果的对比可知,基于 Agent 集成学习情境的 E_Learning 系统具有良好的系统性能,并能有效提高用户的学 习效率。为更好满足用户个性化学习需求,下一步研究的重 境[J].计算机时代,2005(3):3-4. [5] 何烽,魏顺平,韩光艳.E_Learning 在企业的实施与应用[J].经济 师,2004(12):103-104. [6] Duke H C,Jeoungkun K,Soung H K.ERP training with a web- based electronic learning system:The flow theory perspective[J]. International Journal of Human-Computer Studies,2007,65(3): 223-243. [7] 杨威,苑戎.一种基于 Agent 的电子学习体系模型的研究[J].计 算机工程与应用,2004,40(11):156-158. [8] Guidon J, Pierre S. A client-server architecture for an instruc- tional environment based on computer networks and the internet [J].Telematics and Informatics,1996,13(1):11-22. [9] 周必水,谢红标.基于 Web 的智能化学习系统的设计与实现[J]. 计算机工程与设计,2005,26(11):3130-3132. [10] Wooldridge M,Jennings N R.Intelligent agents theory and prac- tice[J].Knowledge Engineering Review,1995,10(2):115-152. [11] Hannoun M,Sichman J S,Boissier O,et al.Dependence relation between roles in a multi-agent system:Towards the detection of inconsistencies in organization[C].Proc of 1st Int Workshop on Multi-Agent Systems and Agent-based Simulation.Berlin,Ger- many:Springer-Verlag,1998:169-182. [12] Chen C M,Hsieh Y L,Hsu S H.Mining learner profile utilizing association rule for web-based learning diagnosis[J].Expert Sys- tems with Applications,2007,33(1):6-22. [13] 周明建,高济.知识管理系统中的用户界面[J].计算机辅助设计 点是扩充用户轮廓记录的学习情境信息,使用数据挖掘算法 与图形学学报,2005,17(5):1101-1106. 发掘用户更多的认知特性,提高 E_Learning 系统的个性化服 务水平。同时结合实际需求不断完善 E_Learning 系统结构, 拓宽 E_Learning 系统的应用领域。 参考文献: [1] 彼得·德鲁克. 巨变时代的管理 [M]. 北京: 机械工业出版社, 2006. [14] Danilowicz C,Nguyen H C.Using user profiles in intelligent in- formation retrieval[C].Proc of the 13th International Symposium on Methodologies for Intelligent Systems. Berlin, Germany: Springer-Verlag,2002:223-231. [15] Probst G,Raub S, Romhardt K.Managing knowledge: Building blocks for success [M]. Chichester, UK: John Wiley and Sons, 2000. [2] 陶峻.知识密集型服务企业的演变趋势[J].生产力研究,2005(3): [16] 周明建,陶俊才.知识管理系统中的知识推送[J].计算机辅助设 15-16. [3] 林东清.知识管理理论与实务[M].北京:电子工业出版社,2005. [4] 胡维华,朱杰杰,王国荣.基于网络教学的智能虚拟电子学习环 计与图形学学报,2006,18(8):1218-1223. [17] 周明建.基于本体的开放式知识管理研究[D].浙江:浙江大学, 2004. (上接第 468 页) 参考文献: [1] 张志涌.精通 Matlab6.5 版[M].北京:北京航空航天大学出版社, [4] 钱能.C++程序设计教程[M].北京:清华大学出版社,2005. [5] 哈特.Win32 系统编程[M].2 版.北京:中国电力出版社,2003. [6] 董长虹. Matlab 接口技术与应用 [M]. 北京: 国防工业出版社, 2003. 2004. [2] 杨波,亓波.精通 Matlab7.0 混合编程 [M].北京:电子工业出版 [7] 张威.Matlab 外部接口编程[M].西安:西安电子科技大学出版 社,2006. 社,2004. [3] 董维国.深入浅出 Matlab7.X 混合编程 [M].北京:机械工业出 [8] 苏金明,黄国明,刘波.Matlab 与外部程序接口[M].北京:电子工 版社,2006. 业出版社,2004.
分享到:
收藏