程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++ call matlab on (mac + xcode )

C++ call matlab on (mac + xcode )

編輯:C++入門知識

 


 

我們的目標是:跑通/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

其中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_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++

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_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





--------------------------------------------2. xcode下跑例程



 

 

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的。

/

/

 

 





--------------------------------------------3. kmeans of matlab under C



 

 

代碼涉及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;
}


 




 


--------------------------------------------4. 利用XCode進行Exception精確定位



最後再說一個xcode調試的小技巧,如何更精確定位錯誤。調試的時候有時會報出很多奇葩的錯誤,看了也不知道哪裡出錯,這時xcode可以定斷點為出錯位置:

 

/

 

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved