我們的目標是:跑通/Applications/MATLAB_R2013a.app/extern/examples/eng_mat/engdemo.cpp
1)修改mac環境變量$PATH & $DYLD_LIBRARY_PATH
終端下:
export PATH='/Applications/MATLAB_R2013a.app/bin':$PATH echo $PATH export DYLD_LIBRARY_PATH='/Applications/MATLAB_R2013a.app/bin/maci64:/Applications/MATLAB_R2013a.app/sys/os/maci64':$DYLD_LIBRARY_PATH echo $DYLD_LIBRARY_PATH
~/.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_mat g++ -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++
可以看到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_mat export PATH='/Applications/MATLAB_R2013a.app/bin':$PATH echo $PATH export DYLD_LIBRARY_PATH='/Applications/MATLAB_R2013a.app/bin/maci64:/Applications/MATLAB_R2013a.app/sys/os/maci64':$DYLD_LIBRARY_PATH echo $DYLD_LIBRARY_PATH g++ -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#include #include #include engine.h #define BUFSIZE 256 int main() { printf(test ); 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, Can't start MATLAB engine ); 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] = ''; engOutputBuffer(ep, buffer, BUFSIZE); engEvalString(ep, D = kmeans(T,3)); mxDestroyArray(T); mxDestroyArray(result); return EXIT_SUCCESS; }