您的位置:首页 > 编程语言 > MATLAB

VS2013和matlab相互调用混合编程

2015-08-21 13:03 585 查看

【环境】VS2013和MATLAB相互调用混合编程

Visual Studio和MATLAB混合编程,有两种方法:

  1 MATLAB调用C程序;

  2 VS调用MATLAB(目前见到的都是VS,其他编译器如codeblocks,或不提供这项功能);

前一种是用MATLAB的mex命令调用VS或其他编译器,将以一定方式编写出的C文件编译成.mexw32(针对win32)或者.mexw64(针对win64),然后MATLAB就可以用调用动态链接库的方式,调用C程序。这一过程中,只需要在安装好编译器的前提下,执行:

mex -setup




mbuild -setup


并按照提示按部就班地帮助MATLAB找到C编译器就可以了。遇到MATLAB找不到Visual Stdio的情况时,可按照官方网站提供的方法,例如如果MATLAB找不到已安装的Visual Studio 2013,则在
http://www.mathworks.com/matlabcentral/fileexchange/44408-matlab-mex-support-for-visual-studio-2013--and-mbuild-
下载官方提供的文件,按照README的要求将文件复制到指定目录下即可。

README:

The files
* msvc120engmatopts.bat
* msvc120opts.bat
* msvc120opts.stp
should be copied to C:\Program Files\MATLAB\R2013a\bin\win64\mexopts .

The files
* msvc120compp.bat
* msvc120compp.stp
should be copied to C:\Program Files\MATLAB\R2013a\bin\win64\mbuildopts .


另一种是反过来,由VS去调用MATLAB,因为归根结底,许多底层的代码都依赖于C/C++语言,如果要使用MATLAB进行实时的数据处理,那么必然是使用C/C++(从操作系统内核、套接字,或者设备)获取数据,再调用MATLAB进行处理。切入正题:

1 首先正确地安装好环境,如下是我使用的环境:

    x86

    Windows 7 

    VS2013

    MATLAB R2010a(安装目录为D:\MATLAB\R2010a)。

2 下面是VS路径的包含

右键项目—属性—VC++目录

               —包含目录,添加D:\MATLAB\R2010a\extern\include;(注意分号)

               —库目录,添加D:\MATLAB\R2010a\extern\lib\win32\microsoft;

       —C/C++(—常规),添加附加包含目录D:\MATLAB\R2010a\extern\include\;

         —链接器

               —常规,添加附加库目录D:\MATLAB\R2010a\extern\lib\win32\microsoft;

               —输入,添加附加依赖项:libeng.lib;libmat.lib;libmex.lib;libmx.lib;mclmcrrt.lib;mclmcr.lib;

3 系统环境变量:PATH里添加D:\MatLab\R2010a\bin\win32; 帮助VS找到MATLAB的提供的动态链接库。

4 注册MATLAB服务器:cmd,在D:\MatLab\R2010a\bin目录下运行

matlab \regserver


大概是开启MATLAB Server模式,接收VS的调用请求吧。

5 下面写C/C++程序:

添加头文件以及动态链接库

#include "engine.h"

#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "libeng.lib")
#pragma comment(lib, "libmx.lib")
#pragma comment(lib, "libmat.lib")


打开引擎(引擎用来调用MATLAB):

Engine* pEng = NULL;

if (!(pEng = engOpen(NULL)))
{
printf("Open matlab enging fail!");
getchar();
return -1;
}


引擎打开函数openEng调用完毕后一定要检查是否打开成功(类似云malloc函数,申请完内存一定要检查是否申请成功),因为就算pEng==NULL,在函数engEvalString执行中也不会抛出异常的,只会导致engGetVariable执行失败,当然咯,因为根本没执行嘛,哪来的variable?

然后可以调用啦,一切的matlab命令都可以通过下面这个函数传入MATLAB执行,类似于Linux的系统调用exec("...")和windows的system("..."):

engEvalString(pEng, "x=0:0.01:pi); y=sin(x); plot(x, y)");


如果要得到MATLAB的返回结果:

engEvalString(pEng, "x=0:0.02:3.14; y=sin(x); plot(x, y)");
mxArray *x= engGetVariable(pEng, "x");
mxArray *y= engGetVariable(pEng, "y");
double * _x = mxGetPr(x);
double * _x = mxGetPr(y);
//此时_x为x数组,_y为y数组


由于MATLAB里面,数据都将看成矩阵来处理,因此返回结果也是以Array的方式返回,如果是单个值,就是array[0],否则为array[0..n-1],如何得到n呢?还是用函数engGetVariable咯,可以先执行n=length(x),再将n传回。

执行结束后,记得关闭引擎

if(pEng)
engClose(pEng);


注意一旦关闭,就不能再使用pEng了,否则会抛出异常。并且,在关闭引擎后,原本在执行过程中得到的figures也会关闭。在我的课题里面,引擎是在程序开始时打开,程序最终退出时才关闭。

6 如果在编译期间出现“找不到XXX.lib”的情况,检查路径是否正确添加,不然就直接复制lib文件到system32吧。。。

7 如果编译链接通过,运行起来还是有异常,检查matlab server是否有注册成功:运行matlab /regserver,再试一试。

8 因为调用MATLAB执行的命令是以字符串形式传入的,千万注意字符串里面的特殊符号、空格。特殊符号前面需要加上反斜杆,若有空格,依据MATLAB的语法,应使用单引号。例如:

engEvalString(pEng,"cd \'E:\\Desktop\\Alilce and Bob\' ");


9 如果遇到ERROR LNK2019,如:

错误    1    error LNK2019: 无法解析的外部符号 _mxGetPr,该符号在函数 "void __cdecl dataProcessing(struct engine *)" (?dataProcessing@@YAXPAUengine@@@Z) 中被引用    C:\Users\OurEDA\Desktop\Ahotspot\Models\RSS CSI Models\matlab\main.obj    matlab
错误    2    error LNK2019: 无法解析的外部符号 _mxDestroyArray,该符号在函数 "void __cdecl dataProcessing(struct engine *)" (?dataProcessing@@YAXPAUengine@@@Z) 中被引用    C:\Users\OurEDA\Desktop\Ahotspot\Models\RSS CSI Models\matlab\main.obj    matlab
错误    3    error LNK2019: 无法解析的外部符号 _engEvalString,该符号在函数 "void __cdecl dataProcessing(struct engine *)" (?dataProcessing@@YAXPAUengine@@@Z) 中被引用    C:\Users\OurEDA\Desktop\Ahotspot\Models\RSS CSI Models\matlab\main.obj    matlab
错误    4    error LNK2019: 无法解析的外部符号 _engOpen,该符号在函数 _main 中被引用    C:\Users\OurEDA\Desktop\Ahotspot\Models\RSS CSI Models\matlab\main.obj    matlab
错误    5    error LNK2019: 无法解析的外部符号 _engClose,该符号在函数 _main 中被引用    C:\Users\OurEDA\Desktop\Ahotspot\Models\RSS CSI Models\matlab\main.obj    matlab
错误    6    error LNK2019: 无法解析的外部符号 _engGetVariable,该符号在函数 "void __cdecl dataProcessing(struct engine *)" (?dataProcessing@@YAXPAUengine@@@Z) 中被引用    C:\Users\OurEDA\Desktop\Ahotspot\Models\RSS CSI Models\matlab\main.obj    matlab
错误    7    error LNK1120: 6 个无法解析的外部命令    C:\Users\OurEDA\Desktop\Ahotspot\Models\RSS CSI Models\Debug\matlab.exe    1    1    matlab


检查MATLAB和VS是否运行在同一平台上,如果MATLAB是x64,那么配置管理器中一定要选中x64,否则选Win32:

右键项目——在配置管理器的下拉菜单里选中正确的平台,然后按照上面所述的过程重新配置路径。



以上~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: