我们的目标是:跑通/Applications/MATLAB_R2013a.app/extern/examples/eng_mat/engdemo.cpp
1)修改mac环境变量$PATH & $DYLD_LIBRARY_PATH
终端下:
export PATH='/Applications/MATLAB_R2013a.app/bin':$PATHecho $PATHexport DYLD_LIBRARY_PATH='/Applications/MATLAB_R2013a.app/bin/maci64:/Applications/MATLAB_R2013a.app/sys/os/maci64':$DYLD_LIBRARY_PATHecho $DYLD_LIBRARY_PATH
其中echo命令用来查看$PATH & $DYLD_LIBRARY_PATH的修改值。这样可以在该终端下修改$PATH & $DYLD_LIBRARY_PATH,但是永久性修改还需要把你要添加的环境变量添加到你主目录下面的.profile或者.bash_profile,如果存在添加进去即可,如果没有生成一个。PS: mac和linux终端一般用bash来进行解析。当bash在读完了整体环境变量的/etc/profile并借此调用其他配置文件后,接下来则是会读取用户自定义的个人配置文件。bash读取的文件总共有三种:
~/.bash_profile ~/.bash_login ~/.profile
其实bash再启动是只读上面文件的一个,而读取的顺序则是依照上面的顺序。也就是说读到bash_profile就不读后面的了,如果bash_profile不存在,后面的才能有机会。
ok,修改过profile之后,注销,重新login就会修改$PATH 和 $DYLD_LIBRARY_PATH了。
2) 跑demo
cd /Applications/MATLAB_R2013a.app/extern/examples/eng_matg++ -o engdemo_terminal engdemo.cpp -I/Applications/MATLAB_R2013a.app/extern/include/ -L/Applications/MATLAB_R2013a.app/bin/maci64 -leng -lmx -lm -lmat -lut -lstdc++
matlab不同版本的要去修改include和link的目录。
可以看到link的几个动态链接库(mac下为.dylib,相当于windows下的dll),eng (libeng.dylib),mx(libmx.dylib),m(libm.dylib),mat(libmat.dylib),ut(libut.dylib),stdc++(标准链接库)分别在/usr/lib/ 和/Applications/MATLAB_R2013a.app/bin/maci64下。
编译完成,运行:
./engdemo_terminal
结果:
运行shell code和在一起就是这样:
cd /Applications/MATLAB_R2013a.app/extern/examples/eng_matexport PATH='/Applications/MATLAB_R2013a.app/bin':$PATHecho $PATHexport DYLD_LIBRARY_PATH='/Applications/MATLAB_R2013a.app/bin/maci64:/Applications/MATLAB_R2013a.app/sys/os/maci64':$DYLD_LIBRARY_PATHecho $DYLD_LIBRARY_PATHg++ -o engdemo_terminal engdemo.cpp -I/Applications/MATLAB_R2013a.app/extern/include/ -L/Applications/MATLAB_R2013a.app/bin/maci64 -leng -lmx -lm -lmat -lut -lstdc++./engdemo_terminal
1)配置项目属性如下:(项目名没改,本来是测试mysql的,不要怀疑我是脑残贴错图……囧)
include:
library:
link:(符号链接)
动态链接库:
这里注意要将/Applications/MATLAB_R2013a.app/bin/maci64下的.dyilb文件都copy到目标文件夹下,不然会报错诸如
dyld: Library not loaded: @rpath/libeng.dylib Referenced from: /Users/mba/Library/Developer/Xcode/DerivedData/mysqlTest-enzwyvjtfdmbfnebxteublhyjhrd/Build/Products/Release/mysqlTest Reason: image not found
或者
dyld: Library not loaded: @rpath/libut.dylib Referenced from: /Users/mba/Library/Developer/Xcode/DerivedData/mysqlTest-enzwyvjtfdmbfnebxteublhyjhrd/Build/Products/Release/mysqlTest Reason: image not found
另外注意,/Applications/MATLAB_R2013a.app/extern/lib/maci64下的fexport.map, mexFunction.map和mexLibrary.map三个map文件是用不到的。
2)更改Debug模式为Release
因为matlab给出的接口是release的,所以我们的项目也要相应改成release的。
代码涉及matlab engine的创建,mex类型的创建,C基本数据类型(double)与matlab mx类型的相互转换,以及如何利用kmeans进行聚类。
//// main.cpp// mysqlTest//// Created by Rachel on 13-12-6.// Copyright (c) 2013年 ZJU. All rights reserved.//#include <stdlib.h>#include <stdio.h>#include <string.h>#include "engine.h"#define BUFSIZE 256int main(){ printf("test\n"); Engine *ep;//matlab engine mxArray *T = NULL, *result = NULL; char buffer[BUFSIZE+1]; double time[10] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0 }; /* * Call engOpen with a NULL string. This starts a MATLAB process * on the current host using the command "matlab". */ if (!(ep = engOpen(""))) { fprintf(stderr, "\nCan't start MATLAB engine\n"); return EXIT_FAILURE; } T = mxCreateDoubleMatrix(1, 10,mxREAL); //transform double to mxArray(double of C++转mxArray) memcpy((void *)mxGetPr(T), (void *)time, sizeof(time)); engPutVariable(ep, "T", T);//传入matlab //transform mxArray to double(mxArray转double) memcpy((void*)time, (void*)mxGetPr(T), sizeof(mxGetPr(T))*10);//注意要乘以time的长度 buffer[BUFSIZE] = '\0'; engOutputBuffer(ep, buffer, BUFSIZE); engEvalString(ep, "D = kmeans(T,3)"); mxDestroyArray(T); mxDestroyArray(result); return EXIT_SUCCESS;}
参考:
1. http://www.cnblogs.com/xitang/archive/2011/09/15/2177924.html
2. stackoverflow
欢迎关注本博客和新浪微博Rachel____Zhang
再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow