本人的工作环境是Windows 7 + Visual Studio 2008 + MATLAB R2010b,还有一套工作环境是Fedora 18 + MATLAB R2012b. 不过,第二套工作环境由于gcc版本太新的问题,一直没有成功,装低版本的gcc也把笔者整的够呛,缺这少那的,你们懂得。所以本文着重介绍第一套环境下的用法。
这里用$(MATLAB)表示你MATLAB的工作路径,也就是你要存放项目中m文件,c文件,h文件的地方。假设你有header.h 和 main.c两个文件,main中包含了header.h。
mex "-I$(MATLAB)" "main.c"
注意I是字母i的大写,I和路径之间没有空格,如
mex "-I\C:\Users\Documents\MATLAB" "main.c"
-I 是为了告诉mex搜索头文件的路径。比如你在header里声明了一个函数,在test.c里实现了这个函数,这三个文件都在$(MATLAB)里面,上面的命令就变成
mex "-I$(MATLAB)" "main.c" "test.c"
注意:"..."是为了处理路径的“畸形”写法,如含有空格的路径名称。如果你路径中没有这些东西
mex -I$(MATLAB) main.c test.c
和上面的命令是等效的。还可以写成
mex -I"$(MATLAB)" main.c test.c
总之还是比较随意的,应该说是随意中透着严谨,如果你用过linux,就不会觉得不正常了。
你想省事吗?你有N个头文件,c文件只有一个吗?
把头文件放到C:\Program Files\Windows SDKs\Windows\v*.0\Include下面吧。
规范化的例子
一般来说一个项目下应该有/src存放c\c++文件,/include存放头文件,等等。我们把项目的顶级目录记为$(MATLAB),文件存放如下
$(MATLAB)/src/main.c
$(MATLAB)/src/test.c
$(MATLAB)/include/header.h
在main.c中
#include<include/header.h>
在test.c中
#include<include/header.h>
假设,MATLAB当前工作于$(MATLAB)下,编译用以下命令
mex -I"$(MATLAB)" "src/main.c" "src/test.c"
以上-I,全是字母i大写,L的小写l是用于提供静态库搜索目录的,方法类似。
最后,我还有一句话:Linux用习惯的你,可能会习惯性的在路径末尾价格斜杠 \ ,如果你在windows下这样用就错了,但是在Linux下是对的。
最新进展:
虽然本人Fedora 18下还没成功装上gcc-4.4.6,但是mex只警告我gcc版本不对,然后还有莫名的错误:error: conflicting types for 'mexFunction'。经过了艰难探索,终于的得出以下结论,在VS2008和VS2010所带的c语言编译器中,函数声明
void f(const int para);
和函数的实现
void f(int para){}
只会给出警告,不会报错。
在mex.h中,mexFunction被声明为
void mexFunction(int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[]);
所以在Windows下,在上面的main.c里,这样写
void mexFunction(int nlhs, mxArray * plhs[], int nrhs, mxArray * prhs[]){}
是可以运行的,然而在Linux下不行,不知道从gcc什么版本起,这种写法就是会报错的。笔者目前还没有在高版本gcc中编译mex C文件出现过问题。这里要吐槽一下,mexFunction错误的写法流传相当广泛,在百度搜索“MATLAB C 混合编程”,前面出来的内容极其类似,给出的例子全是这种错误的写法,真是伤不起啊。
其实,我还有一句话,我不是搞计算机的,只是一个搞算法的科研小屌丝,用Linux是因为下了国外大牛的代码,都是用这个写的。有什么SB的地方,还请见谅。