C++和Matlab混合编程——MATLAB调用c++函数(以svmlight为例)

来源:互联网 发布:软件实施工程师前景 编辑:程序博客网 时间:2024/06/01 07:37

遇到这个问题是因为在使用别人的代码包的时候,人家编写好的是mexw32,而我的系统是64位。当时没有注意到人家把c++源码给了,只要在对应路径下mex a.cpp
即可得到a.mexw64。


最近由于在看svm的相关内容,用到了svmlight的包,涉及到了MATLAB和c++的混合编程。对于mex的一些东西,浪费了好几天时间来调试,今天稍微整理一下。
这是下载好的svm_mex包中的c源文件的内容:
这里写图片描述
事实上在svmlight的源文件包中,是没有上图中mex开头的几个文件的。这几个文件是为了实现MATLAB和c++的混合编程,后来写进去的。但是一般下载下来的svm_mex包,比较老的都是在Linux下编译的或者是32位编译的,也就是说,只有下面的这些文件:
这里写图片描述
我的机器是64位windows,根本用不了,所以需要自己编译。也就是说,目标是生成下列文件:
这里写图片描述
这里我尝试直接在MATLAB下对mexsvmlearn.c(因为需要的函数从该函数入口),使用
mex -g mexsvmlearn.c xxx.c qqq.c aaa.c来执行,但是总是会报错。
一开始总是报错为svm_commom.h文件中的sizeof函数,但是该文件中并没有调用该函数,报错行有一个isnan函数。将其注释,以及对应的svm_commom.c文件中的对应行注释掉之后便不在报错。
但是,在MATLAB里使用mex命令进行编译还是出错,后来使用了下载的包中带的bat文件进行编译就生成了mexw64文件。但是这里还是有问题。
这里写图片描述
原install.bat文件中,这里的第二行patch前面没有rem这个标识符。我对于脚本文件不熟悉,因为它总是报错所以就加上了这个rem标识符,后面就不再报错,能够生成我想要的mexw64文件了,但是会提示,找不到xxx.exp文件。这边我也不是很懂,但是似乎对于mexw64文件的使用不会有影响。

这里进行编译实际上主要是运行了以下几个语句:

cmd /c mex -g -DMATLAB_MEX -DMEX_MEMORY -I../src ../src/mexsvmlearn.c ../src/global.c ../src/svm_learn.c ../src/svm_common.c ../src/svm_hideo.c ../src/mexcommon.c ../src/mem_clean.ccmd /c mex -O  -DMATLAB_MEX -DMEX_MEMORY -I../src  ../src/mexsvmclassify.c ../src/global.c ../src/svm_learn.c ../src/svm_common.c ../src/svm_hideo.c ../src/mexcommon.c ../src/mem_clean.ccmd /c mex -O  -DMATLAB_MEX -DMEX_MEMORY -I../src ../src/mexsinglekernel.c ../src/global.c ../src/svm_learn.c ../src/svm_common.c ../src/svm_hideo.c ../src/mexcommon.c ../src/mem_clean.ccmd /c mex -O  -DMATLAB_MEX -DMEX_MEMORY -I../src ../src/mexkernel.c ../src/global.c ../src/svm_learn.c ../src/svm_common.c ../src/svm_hideo.c ../src/mexcommon.c ../src/mem_clean.c

这里的DMATLAB_MEX 我没查到是什么意义。-g命令是为了后面和debug有关系,如果不加的话不会生成mexw64.pdb文件,也无法进入vs调试。-O好像是和编译优化有关系吧。

然后生成了mexw64文件就可以调用了。先不说我函数调用后来出错的问题。。。(为什么总是这么多问题),下面整理一下MATLAB调用c++函数时在vs里的调试问题
主要参考该教程:https://cn.mathworks.com/matlabcentral/answers/100603-how-can-i-compile-a-matlab-engine-application-using-microsoft-visual-studio-9-0-or-10-0

该教程翻译整理如下:
1. 打开vs,选择文件->新建->项目,然后选择Visual C++->General->空项目
2. 右击源文件,选择添加新建项,新建一个cpp文件,然后将想要调试的c++文件内容拷贝进来。(这里我不是新建项,而是导入一个现有项,也是可以的。)
下面是相关环境的配置,重要。
3. 右击解决方案,进入属性页。
a. C/C++中的“附加包含目录”内,加入该路径

$MATLABROOT\extern\include

这里写图片描述
【这一步我实际上没有加,我在VC++目录里面对包含目录和库目录进行了配置,好像也是没有问题的。】
b. “C/C++预编译头”选项中,选择“不使用预编译头”
这里写图片描述
c. 链接器的“附加库目录”中加入MATLAB的目录,对于64位系统来说:

$MATLABROOT\extern\lib\win64\microsoft

这里写图片描述
d. 配置属性->调试加入环境目标路径,格式如下:

PATH=$matlabroot\bin\win64
  1. 链接器->输入中,加入下列附加依赖项:
libmx.liblibmat.liblibeng.lib

5.【这一步我不太懂,点进连接只是一个文档。我下载打开了,似乎没什么意义。】原文:If compiling on 64-bit Windows, change the target to x64 as mentioned on the following link
http://msdn2.microsoft.com/en-us/library/9yb4317s(VS.80).aspx
You should now be able to build the executable.

6 . 环境变量配置。这里注意配置系统环境变量(下面的那个Path)为:$MATLABROOT\bin\win64
7. 后面就可以运行并且调试目标代码了。

原创粉丝点击