轉自:Linux下c++調用自己編寫的matlab函數:通過mcc動態鏈接庫.so實現_Jaster_wisdom的專欄-CSDN博客
之前在這里和這里調用了matlab自帶的一些函數,是通過matlab引擎來實現的。那里調用的是matlab自帶的函數,那么如果想調用自己寫的.m函數該怎么辦呢?其實很簡單,原理類似,方法也不止一種。這篇筆記我先嘗試通過mcc將.m函數編譯成動態鏈接庫供c++調用的方式。在另一篇筆記中還嘗試了另一種途徑:通過matlab引擎來實現。其實,調用自己編寫的m函數,只是多了一步將自己的matlab函數編譯成動態鏈接庫文件(也就類似自帶的那種eigen.h和libeng.so)。這里練習了一個小例子,展示從c++中調用matlab里面的自己寫的函數。
實驗平臺:ubuntu 12.04 + g++4.6 + matlab2012a
問題描述:
有一個c++程序main.cpp,和一個matlab函數myFunc.m。現在要做這件事:
1)從main.cpp中傳遞2個double類型的數值a和b到myFunc.m中
2)myFunc.m中求和(sum = a+b)
3)main.cpp中接收myFunc.m返回的和并輸出。
思路:
1)設置matlab的編譯器,使用gcc編譯器。編譯m文件成.so。
2)編譯.cpp文件,編譯時調用.so庫(添加.so的路徑到編譯選項)。
步驟:
1)將自己的matlab函數(myFunc.m)編譯成動態鏈接庫
??????? (1)?設定編譯器為gcc,在matlab 命令行依次執行命令mex -setup和mbuild -setup:
[html]??view plain??copy
>>?mex?-setup????????Options?files?control?which?compiler?to?use,?the?compiler?and?link?command?options,?and?the?runtime?libraries?to?link?against.????????Using?the?'mex?-setup'?command?selects?an?options?file?that?is??????placed?in?~/.matlab/R2012a?and?used?by?default?for?'mex'.?An?options???????file?in?the?current?working?directory?or?specified?on?the?command?line???????overrides?the?default?options?file?in?~/.matlab/R2012a.?????????To?override?the?default?options?file,?use?the?'mex?-f'?command??????(see?'mex?-help'?for?more?information).????The?options?files?available?for?mex?are:??????1:?/opt/MATLAB/R2012a/bin/mexopts.sh?:?????????Template?Options?file?for?building?gcc?MEX-files?????????0:?Exit?with?no?changes????Enter?the?number?of?the?compiler?(0-1):??1??????/opt/MATLAB/R2012a/bin/mexopts.sh?is?being?copied?to?~/.matlab/R2012a/mexopts.sh????cp:?cannot?create?regular?file?`~/.matlab/R2012a/mexopts.sh':?Permission?denied????**************************************************************************????Warning:?The?MATLAB?C?and?Fortran?API?has?changed?to?support?MATLAB??????????????variables?with?more?than?2^32-1?elements.??In?the?near?future??????????????you?will?be?required?to?update?your?code?to?utilize?the?new??????????????API.?You?can?find?more?information?about?this?at:??????????????http://www.mathworks.com/help/techdoc/matlab_external/bsflnue-1.html?????????????Building?with?the?-largeArrayDims?option?enables?the?new?API.???**************************************************************************????>>?mbuild?-setup?????????Options?files?control?which?compiler?to?use,?the?compiler?and?link?command??????options,?and?the?runtime?libraries?to?link?against.????????Using?the?'mbuild?-setup'?command?selects?an?options?file?that?is??????placed?in?~/.matlab/R2012a?and?used?by?default?for?'mbuild'.?An?options???????file?in?the?current?working?directory?or?specified?on?the?command?line???????overrides?the?default?options?file?in?~/.matlab/R2012a.?????????To?override?the?default?options?file,?use?the?'mbuild?-f'?command?(see?'mbuild?-help'?for?more?information).????The?options?files?available?for?mbuild?are:??????1:?/opt/MATLAB/R2012a/bin/mbuildopts.sh?:?????????Build?and?link?with?MATLAB?Compiler?generated?library?via?the?system?ANSI?C/C++?compiler?????????0:?Exit?with?no?changes????Enter?the?number?of?the?compiler?(0-1):??1??????/opt/MATLAB/R2012a/bin/mbuildopts.sh?is?being?copied?to?~/.matlab/R2012a/mbuildopts.sh????cp:?cannot?create?regular?file?`~/.matlab/R2012a/mbuildopts.sh':?Permission?denied??>>??
???????(2) 在matlab中,編寫myFunc.m文件內容如下:
[html]??view plain??copy
function?[?C?]?=?myFunc(A,?B)????C?=?A+B;????end??
???????(3) 生成myFunc.m的動態鏈接庫(.so)
[html]??view plain??copy
>>?mcc?-W?cpplib:libmyFunc?-T?link:lib?myFunc.m?-c??Warning:?MATLAB?Toolbox?Path?Cache?is?out?of?date?and?is?not?being?used.??Type?'help?toolbox_path_cache'?for?more?info???>>???
等待數秒,完成。可以看到myFunc.m所在的目錄下生成了多個文件:
[html]??view plain??copy
$?ls??libmyFunc.cpp??libmyFunc.ctf??libmyFunc.exports??libmyFunc.h??libmyFunc.so??main.cpp??mccExcludedFiles.log??myFunc.m??readme.txt??
命令解釋:其中-W是控制編譯之后的封裝格式;cpplib是指編譯成C++的lib;cpplib冒號后面是指編譯的庫的名字;-T表示目標,link:lib表示要連接到一個庫文件的目標,目標的名字即是.m函數的名字。-c表明需要生成.ctf文件,比如本例如果不加-c就不會生成“libmyFunc.ctf”。
生成的文件中打開“libmyFunc.h”可以看到一行:
extern LIB_libmyFunc_CPP_API void MW_CALL_CONV myFunc(int nargout, mwArray& C, const mwArray& A, const mwArray& B);?
這個就是我們的myFunc.c函數待會兒在c++中調用時的接口。有4個參數,第一個是參數個數,第二個是用來接收函數返回值的,后面2個是從c++中傳遞進來的變量。我們還會用到“libmyFunc.h”中的另外2個函數:libmyFuncInitialize()初始化,和注銷libmyFuncTerminate()。
2)編寫main.cpp,代碼如下:
[cpp]??view plain??copy
#include?<iostream>??#include?"mclmcr.h"??#include?"matrix.h"??#include?"mclcppclass.h"??#include?"libmyFunc.h"??#include?"mclmcrrt.h"????using?namespace?std;????int?main()?{????????//?initialize?lib,這里必須做初始化!??????if(?!libmyFuncInitialize())??????{??????????std::cout?<<?"Could?not?initialize?libmyFunc!"?<<?std::endl;??????????return?-1;??????}????????//?用戶輸入2個數值??????double?a,?b;??????cout<<"Please?input?2?numbers?<a?b>?and?then?press?enter:?"<<endl;??????cin?>>?a;??????cin?>>?b;????????double?c;?//used?to?receive?the?result????????//?為變量分配內存空間,?maltab只有一種變量,就是矩陣,為了和c++變量接軌,設置成1*1的矩陣??????mwArray?mwA(1,?1,?mxDOUBLE_CLASS);?//1,1表示矩陣的大小,?mxDOUBLE_CLASS表示變量的精度??????mwArray?mwB(1,?1,?mxDOUBLE_CLASS);??????mwArray?mwC(1,?1,?mxDOUBLE_CLASS);????????//?調用類里面的SetData函數給類賦值??????mwA.SetData(&a,?1);??????mwB.SetData(&b,?1);????????//?調用自己的函數,求和。??????myFunc(1,?mwC,?mwA,?mwB);????????c?=?mwC.Get(1,?1);????????cout<<"The?sum?is:?"<<c<<endl;????????//?后面是一些終止調用的程序??????//?terminate?the?lib??????libmyFuncTerminate();????????//?terminate?MCR??????mclTerminateApplication();??????????return?EXIT_SUCCESS;??}??
3)編譯main.cpp函數,調用libmyFunc.so
[html]??view plain??copy
$?g++?-o?main?-I.?-I/opt/MATLAB/R2012a/extern/include?-L.?-L/opt/MATLAB/R2012a/runtime/glnxa64?main.cpp?-lmyFunc?-lm?-lmwmclmcrrt?-lmwmclmcr??
開始編譯時也遇到一些問題,主要是鏈接庫路徑問題導致的編譯錯誤,詳細錯誤匯總在另篇筆記里(?點此查看?)。
編譯成功后,需要裝一下MCR Installer,步驟點此。
運行結果:
[html]??view plain??copy
$?./main???Warning:?latest?version?of?matlab?app-defaults?file?not?found.??Contact?your?system?administrator?to?have?this?file?installed??Please?input?2?numbers?<a?b>?and?then?press?enter:???10?100??The?sum?is:?110????$?./main???Warning:?latest?version?of?matlab?app-defaults?file?not?found.??Contact?your?system?administrator?to?have?this?file?installed??Please?input?2?numbers?<a?b>?and?then?press?enter:???1?1??The?sum?is:?2??
源代碼及編譯過程中的所有文件已打包,點擊這里可以下載。
參考:
c++調用matlab生成的Dll動態連接庫 - OSCHINA - 中文開源技術交流社區
Linux下動態鏈接庫的創建和使用及C調用matlab動態庫問題_ylf13的專欄-CSDN博客
淺析將matlab函數編譯成dll供Cpp調用的方法 - 51CTO.COM
matlab:linux環境中將m文件編譯成動態鏈接庫 - Mr.Rico - 博客園
matlab練習程序(c/c++調用matlab<dll>) - Dsp Tian - 博客園
科學網—liuzy2011的個人資料
c++調用matlab生成的Dll動態連接庫_鄭海波(莫川)的CSDN博客-CSDN博客_c++調用matlab生成的dll
How to call Matlab from C++ code? - Stack Overflow
?
總結
以上是生活随笔為你收集整理的【转】Linux下c++调用自己编写的matlab函数:通过mcc动态链接库.so实现的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。