Windows下基于mingw的mex开发

来源:互联网 发布:淘宝买恒压阀 编辑:程序博客网 时间:2024/06/07 13:36

1. mex是什么

mex是Matlab提供的一种混合编程方式。通过mex,用户可以在Matlab中调用C/C++或者Fortran编写的计算程序,加速Matlab内部的矩阵运算(尤其是加速Matlab代码中的for循环)。mex本质上是一个动态链接库文件,可以被Matlab动态加载并执行。

本文介绍Windows环境下基于mingw的mex开发流程和一些注意事项。

2. mex开发流程

首先运行mex -setup配置mex开发环境,主要是设置编译器。

一般Windows下最常用的是采用Visual Studio进行开发;在Unix系统下一般是采用gcc开发。

Windows下利用mingw进行Matlab mex开发主要有两种方式:

  1. 普通方式—使用Matlab的mex命令
    Matlab提供了mex命令,可以方便地将C/C++或者Fortran代码编译为mex文件。mex命令的选项与mingw有很多相似之处,例如-I,-L,-l等等,熟悉mingw环境的童鞋很容易上手。mex命令支持的全部选项可以输入mex -help或者doc mex查看。

    mex -v -g -I %MEX_INCLUDE% -L %MEX_LIBRARY% xx.c -lmx -lmex -lmat -leng -lyy -lzz

  2. 使用gnumex
    下载gnumex,参照下面方式进行安装。
    此时输入mex -setup就会多出一个选项,选择gnumex即可。以后使用mex命令则默认调用的是mingw编译器。
    但是这种方式有两个局限。首先,如其名所暗示的那样,gnumex只能利用mingw进行mex开发,若使用mbuild将m代码编译为可执行文件或者DLL文件,此时不能使用mingw。因为gnumex只是修改了mexopts.bat文件。 并没有修改mbuild相关的配置文件。其次,需要额外安装工具箱。比较麻烦。

上述两种方法一般均需要在Matlab环境下操作,实际上,我们完全可以脱离Matlab环境,基于mingw编译器完成mex文件的开发和调试。这主要是基于以下两个事实:1. mex文件本质上是一个动态链接库文件,可以由相应的编译器生成。2. Matlab为Matlab与C/C++混合编程提供了相应的函数库(libmx.lib, libmex.lib, libmat.lib和libeng.lib),这为我们在Matlab环境之外进行mex开发提供了可能性,因为我们连接库中的代码调用Matlab完成相应功能。

注意:这里所说的是mex开发可以脱离Matlab环境,而mex文件实际运行时还需依赖Matlab运行时环境!

3. mingw mex开发实例

首先确保MATLAB_HOME已经加入环境变量:

set MATLAB_HOME=D:\Program Files\MATLAB\R2010apath %MATLAB_HOME%/bin;%MATLAB_HOME%/bin/win32;%path%

MATLAB_HOME代表MATLAB安装目录,在Matlab Command下输入matlabroot可以获得其值。

Makefile如下:

MATLABROOT ?= "D:\Program Files\MATLAB\R2010a"CC          = gccCCFLAGS     = -I${MATLABROOT}/extern/include -L${MATLABROOT}/extern/lib/win32/microsoftMEXLIBS     = -llibmex -llibmat -llibeng -llibmx -llibutall: yprime.mexw32yprime.mexw32: yprime.c    @${CC} ${CCFLAGS} -shared -fPIC -o $@  $< ${CCFLAGS}clean:    @-rm *.mexw32.*

以下是另一个版本(调用Matlab mex命令,需要确保<MATLABROOT>/bin<MATLABROOT>/bin/win32已经加入系统PATH环境变量):

MATLABROOT ?= "D:\Program Files\MATLAB\R2010a"all: yprime.mexw32yprime.mexw32: yprime.c    @mex -g yprime.cclean:    @-rm *.mexw32.*

在Windows下,脱离Matlab环境,利用mingw环境进行mex开发,并且利用Makefile进行mex项目管理,可以更加方便地控制构建流程,具有极大的灵活性。例如,如果mex需要连接第三方库,可以这样写(以OpenCV为例):

MATLABROOT ?= D:\Progra~1\MATLAB\R2010aOPENCVROOT ?= D:\Bigben\usr\opencvOPENCVLIBS  = -lopencv_calib3d242.dll -lopencv_contrib242.dll -lopencv_core242.dll             -lopencv_features2d242.dll -lopencv_flann242.dll -lopencv_gpu242.dll             -lopencv_highgui242.dll -lopencv_imgproc242.dll -lopencv_legacy242.dll             -lopencv_ml242.dll -lopencv_nonfree242.dll -lopencv_objdetect242.dll             -lopencv_photo242.dll -lopencv_stitching242.dll -lopencv_ts242             -lopencv_video242.dll -lopencv_videostab242.dllMEXLIBS     = -llibmex -llibeng -llibmat -llibmx -llibutCC          = g++CCFLAGS     = -I${OPENCVROOT}/include -L${OPENCVROOT}/lib -I${MATLABROOT}/extern/include             -L${MATLABROOT}/extern/lib/win32/microsoft             -Wl,--dll.PHONY: allall: mexCascadeClassifier.mexw32mexCascadeClassifier.mexw32: mexCascadeClassifier.cpp    @${CC} ${CCFLAGS} -shared -fPIC -O2 -o $@ $< ${OPENCVLIBS} ${MEXLIBS}    @strip $@clean:    @-rm *.o *.mexw32

当然,利用mex命令也能很容易实现这一点。运行mex -help,可以看到mex支持-I-L-l选项。-I用于添加头文件搜索路径,-L添加库文件搜索路径,-l用于指定要连接的库文件名称。这些都与gcc/g++类似。例如,要连接OpenCV,也可以这样写:

mex -I${OPENCVROOT}/include -L${OPENCVROOT}/lib -I${MATLABROOT}/extern/include     -L${MATLABROOT}/extern/lib/win32/microsoft     mexCascadeClassifier.cpp ${OPENCVLIBS} ${MEXLIBS}

compile.m代码如下:

MATLABROOT = matlabroot;OPENCVROOT = 'D:\Bigben\usr\opencv';cc_include = '';cc_include = [cc_include '-I' fullfile(MATLABROOT, '/include')];cc_include = [cc_include '-I' fullfile(OPENCVROOT, '/include')];cc_library = '';cc_library = [cc_library '-L' fullfile(MATLABROOT, '/extern/lib/win32/microsoft')];cc_library = [cc_library '-L' fullfile(OPENCVROOT, '/lib')];mex mexCascadeClassifier.cpp ${OPENCVLIBS} ${MEXLIBS}
1 0