Windows下基于mingw的mex开发

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\R2010a
path %MATLAB_HOME%/bin;%MATLAB_HOME%/bin/win32;%path%

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

Makefile如下:

MATLABROOT ?= "D:\Program Files\MATLAB\R2010a"

CC          = gcc
CCFLAGS     = -I${MATLABROOT}/extern/include -L${MATLABROOT}/extern/lib/win32/microsoft
MEXLIBS     = -llibmex -llibmat -llibeng -llibmx -llibut

all: yprime.mexw32

yprime.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.mexw32

yprime.mexw32: yprime.c
    @mex -g yprime.c

clean:
    @-rm *.mexw32.*

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

MATLABROOT ?= D:\Progra~1\MATLAB\R2010a
OPENCVROOT ?= D:\Bigben\usr\opencv

OPENCVLIBS  = -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.dll
MEXLIBS     = -llibmex -llibeng -llibmat -llibmx -llibut

CC          = g++
CCFLAGS     = -I${OPENCVROOT}/include -L${OPENCVROOT}/lib -I${MATLABROOT}/extern/include 
            -L${MATLABROOT}/extern/lib/win32/microsoft 
            -Wl,--dll

.PHONY: all

all: mexCascadeClassifier.mexw32

mexCascadeClassifier.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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值