ubuntu16.04下MATLAB和C++混編(基於ROS,不含VS類別的編譯器)
如題,真的是一個很艱辛的過程,在windows下的話,在VS下的話,一切問題都不是問題。
但是,現在需要在ubuntu下的ROS中實現c++和MATLAB混編,就很雞肋。
------------------------------------------------------------------------------------------------------------------------------------------------------------
0.在終端進入matlab操作區域
matlab -nodesktop -nosplash
1.設定matlab的編譯器
輸入並執行如下命令:mex –setup
在出現的編譯器中,選擇mex -setup C++
再輸入命令:mbuild –setup
再選擇mex -setup C++ -client MBUILD
設定結束,出現 “MBUILD 配置為使用 'g++' 以進行 C++ 語言編譯。”
2.編寫.m檔案
function result=lib_add(a,b)
%UNTITLED4 此處顯示有關此函式的摘要
% 此處顯示詳細說明
result = a+b;
end
3.編譯.m檔案
在ubuntu下編譯.m檔案,後面在路徑配置的時候很關鍵。
執行下面的程式碼時,要解決gcc和g++的版本問題,在前面的部落格中已經提到在UBUNTU16.04中要如何解決這個問題。
此外還遇到了找不到libstdc++.so.6的問題,此時全盤搜尋,再將該檔案複製到對應的MATLAB資料夾中即可。
程式碼要在MATLAB中編!//其實在終端開啟MATLAB,輸入命令也是可以的。
mcc -W cpplib:libMypr -T link:lib FrequencyDomain.m
上述程式碼編譯完成之後,生成libMypr.h、libMypr.cpp、 libMypr.so、 libMypr.exports這四個檔案,也是我們在c++中呼叫所需要的
4.編寫C++程式碼,並將.cpp檔案和編譯的.m檔案放在統一資料夾下
#include "mclmcrrt.h"
#include "mclmcr.h"
#include "mclcppclass.h"
#include "matrix.h"
#include <iostream>
#include "libMypr.h"using namespace std;
int main(int argc, char* argv[])
{
//初始化, 在C++呼叫matlab時,必須要進行初始化。
if( !libMyprInitialize())
{
printf("Could not initialize !");
return -1;
}double a[3] = {1,2,3};
mwArray m_a(3,1, mxDOUBLE_CLASS);
m_a.SetData(a,3);
double b[3] = {4,5,6};
mwArray m_b(3,1, mxDOUBLE_CLASS);
m_b.SetData(b,3);
mwArray result;
lib_add(3,result,m_b,m_b);// 後面是一些終止呼叫的程式
// terminate the lib
libMyprTerminate();
return 0;
}
5.編譯方法一,通過指令:
編譯之前,先新建一個test資料夾,把所有的檔案都放進去吧,包括cpp檔案中include的各種matlab中的h檔案。
1)生成編譯檔案test.o
g++ -c test.cpp /usr/local/MATLAB/R2017b/extern/include/ -o test.o
改進為:g++ -c test.cpp -L/home/zp/桌面/test/mat.h-L/home/zp/桌面/test/mclmcr.h -L/home/zp/桌面/test/libMypr.h -L/home/zp/桌面/test/matrix.h -L/home/zp/桌面/test/mclbase.h -L/home/zp/桌面/test/mclcppclass.h -L/home/zp/桌面/test/mclmcrrt.h -L/home/zp/桌面/test/tmwtypes.h -o test.o
g++: warning: /usr/local/MATLAB/R2017b/extern/include/: linker input file unused because linking not done
使用改進後的語句就沒有上述的warning啦,主要是把include中的h檔案都寫出來,這樣才能正確將輸入全部用起來,並生成o檔案。
2)設定matlab動態檔案路徑
export LD_LIBRARY_PATH="/home/zp/桌面/test:/usr/local/MATLAB/R2017b/runtime/glnxa64 :$LD_LIBRARY_PATH"
3)生成執行檔案testApp
g++ -o testApp test.o -L/home/zp/桌面/test-/usr/local/MATLAB/R2017b/runtime/glnxa64 -lmwmclmcrrt -L/home/zp/桌面/test-lMypr
修改後:
g++ -o testApp test.o -L/home/zp/桌面/test-/usr/local/MATLAB/R2017b/runtime/glnxa64 -L/home/zp/桌面/test/libmwmclmcrr.so -L/home/zp/桌面/test/libMypr.so
error:/usr/bin/ld: 找不到 -lmwmclmcrrt
/usr/bin/ld: 找不到 -lMypr
solution:
聯網:(libXX是libmwmclmcrrt)
$ sudo apt-get install apt-file
$ apt-file update
$ apt-file search libXX.so
apt-file 將列出所有包含libXX.so檔案的apt包,
選擇相應的包用apt-get安裝即可。通常請選擇帶dev的包安裝,上述三步中,第二步的時間較長。
然鵝,執行第三步的搜尋之後,並未出現所謂的安裝包,搜尋結果為空。
此路不通。
繼續,使用修改後的程式碼,直接找到對應的.so檔案,然後指定地址即可。找不到的問題解決了。
然鵝,編譯又出現了新錯誤:
test.o:在函式‘main’中:
test.cpp:(.text+0x29):對‘libMyprInitialize’未定義的引用
test.cpp:(.text+0x12e):對‘add(int, mwArray&, mwArray const&, mwArray const&)’未定義的引用
test.cpp:(.text+0x133):對‘libMyprTerminate’未定義的引用
test.o:在函式‘mwException::mwException()’中:
test.cpp:(.text._ZN11mwExceptionC2Ev[_ZN11mwExceptionC5Ev]+0x42):對‘mclcppCreateError_proxy’未定義的引用
test.o:在函式‘mwException::mwException(char const*)’中:
test.cpp:(.text._ZN11mwExceptionC2EPKc[_ZN11mwExceptionC5EPKc]+0x56):對‘mclcppCreateError_proxy’未定義的引用
test.o:在函式‘mwException::mwException(error_info*, bool)’中:
test.cpp:(.text._ZN11mwExceptionC2EP10error_infob[_ZN11mwExceptionC5EP10error_infob]+0x5f):對‘ref_count_obj_addref_proxy’未定義的引用
test.cpp:(.text._ZN11mwExceptionC2EP10error_infob[_ZN11mwExceptionC5EP10error_infob]+0x76):對‘mclcppCreateError_proxy’未定義的引用
test.o:在函式‘mwException::~mwException()’中:
test.cpp:(.text._ZN11mwExceptionD2Ev[_ZN11mwExceptionD5Ev]+0x34):對‘ref_count_obj_release_proxy’未定義的引用
test.o:在函式‘mwException::what() const’中:
test.cpp:(.text._ZNK11mwException4whatEv[_ZNK11mwException4whatEv]+0x25):對‘error_info_get_message_proxy’未定義的引用
test.o:在函式‘mwException::raise_error()’中:
test.cpp:(.text._ZN11mwException11raise_errorEv[_ZN11mwException11raise_errorEv]+0x2a):對‘mclcppGetLastError_proxy’未定義的引用
test.o:在函式‘mwArray::mwArray()’中:
test.cpp:(.text._ZN7mwArrayC2Ev[_ZN7mwArrayC5Ev]+0x35):對‘mclGetEmptyArray_proxy’未定義的引用
test.o:在函式‘mwArray::mwArray(unsigned long, unsigned long, mxClassID, mxComplexity)’中:
test.cpp:(.text._ZN7mwArrayC2Emm9mxClassID12mxComplexity[_ZN7mwArrayC5Emm9mxClassID12mxComplexity]+0x50):對‘mclGetMatrix_proxy’未定義的引用
test.o:在函式‘mwArray::~mwArray()’中:
test.cpp:(.text._ZN7mwArrayD2Ev[_ZN7mwArrayD5Ev]+0x24):對‘ref_count_obj_release_proxy’未定義的引用
test.o:在函式‘mwArray::SetData(double*, unsigned long)’中:
test.cpp:(.text._ZN7mwArray7SetDataEPdm[_ZN7mwArray7SetDataEPdm]+0x2b):對‘array_ref_set_numeric_mxDouble_proxy’未定義的引用
collect2: error: ld returned 1 exit status
gcc和g++的指令說明:https://blog.csdn.net/arackethis/article/details/43342655
-o:指定生成可執行檔案的名稱。使用方法為:g++ -o afile file.cpp file.h ... (可執行檔案不可與待編譯或連結檔案同名,否則會生成相應可執行檔案且覆蓋原編譯或連結檔案),如果不使用-o選項,則會生成預設可執行檔案a.out。
-c:只編譯不連結,只生成目標檔案。
6.編譯方法二,通過CMakelists:
make的時候,出現了以下解決了很久很久的問題,唉:
[100%] Linking CXX executable ../VIO
../../../../lib/libORB_SLAM2.so:對‘mclGetMatrix_proxy’未定義的引用
../../../../lib/libORB_SLAM2.so:對‘error_info_get_message_proxy’未定義的引用
../../../../lib/libORB_SLAM2.so:對‘mclcppGetLastError_proxy’未定義的引用
../../../../lib/libORB_SLAM2.so:對‘array_ref_set_numeric_mxDouble_proxy’未定義的引用
../../../../lib/libORB_SLAM2.so:對‘mclGetEmptyArray_proxy’未定義的引用
../../../../lib/libORB_SLAM2.so:對‘mclcppCreateError_proxy’未定義的引用
../../../../lib/libORB_SLAM2.so:對‘ref_count_obj_release_proxy’未定義的引用
../../../../lib/libORB_SLAM2.so:對‘array_ref_get_numeric_mxDouble_proxy’未定義的引用
../../../../lib/libORB_SLAM2.so:對‘FrequencyDomain(int, mwArray&, mwArray const&, mwArray const&, mwArray const&, mwArray const&, mwArray const&, mwArray const&)’未定義的引用
collect2: error: ld returned 1 exit status
CMakeFiles/VIO.dir/build.make:300: recipe for target '../VIO' failed
make[2]: *** [../VIO] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/VIO.dir/all' failed
make[1]: *** [CMakeFiles/VIO.dir/all] Error 2
Makefile:127: recipe for target 'all' failed
make: *** [all] Error 2
找了快一天半的原因,發現是沒新增好mylib.so,需要將其在cmakelists中進行連線,並且再生成共享庫的內部要加入MATLAB生成的h檔案和cc檔案以及so檔案。
百度查詢相關問題的時候,大多是mclmcrrt.lib未加入,但是我並沒有找到,問題也解決了。
相關文章
- VS CODE下編譯ROS程式編譯ROS
- C++和MATLAB混編的問題集錦C++Matlab
- python與matlab混編PythonMatlab
- VS設定 LLVM-Clang 編譯器進行編譯C++專案LVM編譯C++
- 關於C和C++混編的一些心得C++
- cmake混編.c和.cpp需要注意的地方--指定兩種編譯器編譯
- 在C,C++,java和python執行時直譯器和編譯器的區別C++JavaPython編譯
- C++編譯器認為的指標型別(靜態聯編)C++編譯指標型別
- ollvm在VS2017下編譯LVM編譯
- 編譯器的自展和自舉、交叉編譯編譯
- C++編譯器優化C++編譯優化
- 淺談彙編器、編譯器和直譯器編譯
- Leptonica在VS2010中的編譯一,編譯它依賴於庫編譯
- QML::qml與c++混編C++
- c++模板類的使用,編譯的問題C++編譯
- linux下基於官方原始碼編譯ipoptLinux原始碼編譯
- QT creator 中c和c++混編問題QTC++
- windows vs 編譯postgresqlWindows編譯SQL
- 使用vs2022編譯assimp,並基於OpenGL載入模型編譯模型
- OC和Swift混編Swift
- Windows10 VS2017 C++編譯Linux程式WindowsC++編譯Linux
- gcc 和 g++ 的聯絡和區別,使用 gcc 編譯 c++GC編譯C++
- VS在 x64 編譯環境下使用匯編函式編譯函式
- 安裝c, c++編譯器 on AIXC++編譯AI
- 在windows上配置vs code編譯除錯c/c++Windows編譯除錯C++
- 【ROS教程】用CLion編譯和除錯ROS包的全流程及可能遇到的問題ROS編譯除錯
- [譯] 理解編譯器 —— 從人類的角度(版本 2)編譯
- Leptonica在VS2010中的編譯二,編譯 Leptonica1.68編譯
- 編譯原理——C++版桌面計算器編譯原理C++
- 不一樣的玩法兒:基於反編譯器的Frida支援編譯
- ROS——無人機ROS模擬包 rotors_simulator 編譯教程ROS無人機編譯
- windows下基於cmake配置opencv並使用visual studio編譯WindowsOpenCV編譯
- Vue3原始碼分析——編譯模組和編譯器Vue原始碼編譯
- Github基於Web的編輯器GithubWeb
- C++ 編譯過程C++編譯
- OC和Swift混編經驗Swift
- Objective-C和Swift混編ObjectSwift
- iOS UMeng OC和Swift混編iOSSwift