Ubuntu 18.04下通过Matlab runtime使用c++调用自己编写的matlab函数
文章目录
前言
写这篇博文的主要目的就是记录一下自己在linux系统下,通过Matlab runtime,使用c++调用自己编写的matlab函数所需要的问题,网上教程很多,但是对自己来说,有一点乱。通过记录,帮助自己及别人熟悉这个过程,说一下自己安装过程中的问题及浅薄见解。
一、安装Matlab runtime
Matlab runtime作用就是在电脑没有安装MATLAB环境下,去调用MATLAB的相关函数,安装过程如下:
环境下载:https://ww2.mathworks.cn/products/compiler/matlab-runtime.html
安装帮助:https://ww2.mathworks.cn/help/compiler/install-the-matlab-runtime.html
1.1下载Matlab runtime
注:一定要注意,下载的版本一定要跟你编译的matlab版本相对应。
我的matlab版本为R2018b,所有我下载的Matlab runtime的版本为9.5
1.2安装Matlab runtime
先将压缩包进行解压
unzip MCR_R2018b_glnxa64_installer.zip
然后进入我们的解压文件夹,进行安装,网上很多是使用默认安装方式进行安装的,
./install -mode silent -agreeToLicense yes
但是他会有一个东西安装不上,于是我就采用另外的方法,直接通过他文件夹里面的install的方式进行安装。
sudo ./install
这样安装的话,会弹出图形化安装界面,按照下一步,下一步进行操作。
安装文件夹最好按照默认的,也可以改成自己的想要设置的目录。
最后会出现这个环境变量,我的没有添加到 ~/.bashrc 里面,网上很多教程都是进行设置的,我没有,但是最后成功了。
不知道为什么,我添加完成之后,所有的工作空间和功能包进行catkin_make的时候,都会报错,注释掉之后,就不会有问题。不知道为什么。
经过上面操作,Matlab runtime就安装完成了。
二、matlab .m文件编译C++
1.实例
代码如下(示例):
function [ C ] = myFunc(A, B)
C = A+B;
end
2.编译
windows环境下的matlab编译的话是生成 dll 之类的文件,linux环境下生成的是 .so 文件,最好是在linux环境下的matlab进行编译。
>> mex -setup
MEX 配置为使用 'gcc' 以进行 C 语言编译。
警告: MATLAB C 和 Fortran API 已更改,现可支持
包含 2^32-1 个以上元素的 MATLAB 变量。不久以后,
您需要更新代码以利用
新的 API。您可以在以下网址找到相关详细信息:
http://www.mathworks.com/help/matlab/matlab_external/upgrading-mex-files-to-use-64-bit-api.html。
要选择不同的语言,请从以下选项中选择一种命令:
mex -setup C++
mex -setup FORTRAN
MEX 配置为使用 'g++' 以进行 C++ 语言编译。
警告: MATLAB C 和 Fortran API 已更改,现可支持
包含 2^32-1 个以上元素的 MATLAB 变量。不久以后,
您需要更新代码以利用
新的 API。您可以在以下网址找到相关详细信息:
http://www.mathworks.com/help/matlab/matlab_external/upgrading-mex-files-to-use-64-bit-api.html。
>> mbuild -setup
MBUILD 配置为使用 'gcc' 以进行 C 语言编译。
要选择不同的语言,请从以下选项中选择一种命令:
mex -setup C++ -client MBUILD
mex -setup FORTRAN -client MBUILD
MBUILD 配置为使用 'g++' 以进行 C++ 语言编译。
记住,再输入mex -setup之后,选择第一项。
输入完mbuild -setup之后,也记着选择第一项。
最后通过以下命令,等待几秒,生成编译后的文件。
mcc -W cpplib:libmyFunc -T link:lib myFunc.m -C
这三个文件是必须需要的,.ctf包含了你代码里面大量的运算信息。必须要有,我之前是利用matalb自带的APP里面生成的C文件,没有生成.ctf这个文件,导致无法运行。
.h里面包含你写的函数接口,包括初始化函数、终止函数之类的。
.so是编译所需要的动态库。
通过上述操作,就完成了所需要文件的编译工作。
我们创建一个main.cpp文件,完成对编译文件的调用
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include "mclmcrrt.h"
#include "mclmcr.h"
#include "matrix.h"
#include "mclcppclass.h"
#include "myFunc.h"
using namespace std;
int main() {
// Set up the application state for the MATLAB Runtime instance created in the application.
if (!mclInitializeApplication(NULL,0))
{
std::cerr << "could not initialize the application properly"
<< std::endl;
return -1;
}
// initialize lib,这里必须做初始化!
if( !myFuncInitialize())
{
std::cout << "Could not initialize libmyFunc!" << std::endl;
return -1;
}
// 用户输入2个数值
double a, b;
a =10; b=20;
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
myFuncTerminate();
// terminate MCR
mclTerminateApplication();
return EXIT_SUCCESS;
}
下面的操作就是让文件跑起来了
三、运行走起来
1.实例
在主文件夹创建test文件夹,
文件夹里面包含以上文件。
src里面包含你的main.cpp文件,include包含你编译的.h文件
CMakeList.txt 文件内容参考如下:
cmake_minimum_required(VERSION 2.8.3)
set(PROJECT_NAME test)
project(${PROJECT_NAME})
# List COMMAND
set(CMAKE_CXX_FLAGS "-g -Wall -std=c++0x")
# matlab
set(MATLAB_ROOT /usr/local/MATLAB/MATLAB_Runtime/v95/)
include_directories(${MATLAB_ROOT}extern/include/)
LINK_DIRECTORIES(${MATLAB_ROOT}runtime/glnxa64/)
# libMypr
set(MYPR /home/liukaishu/test/)
# 前提是已将.h文件和.so文件分别放在include和src中。
include_directories(${MYPR}include/)
LINK_DIRECTORIES(${MYPR}src/)
#set(SRCS main.cpp)
#add_executable(${PROJECT_NAME} ${SRCS})
add_executable(testa src/main.cpp)
target_link_libraries(testa /usr/local/MATLAB/MATLAB_Runtime/v95/bin/glnxa64/libmwmclmcr.so)
target_link_libraries(testa /usr/local/MATLAB/MATLAB_Runtime/v95/bin/glnxa64/libmwmclmcrrt.so)
include_directories("/usr/local/MATLAB/MATLAB_Runtime/v95/extern/include")
target_link_libraries(testa /home/liukaishu/test/libmyFunc.so)
上面的路径按照自己实际路径进行修改。
2.编译
mkdir build
cd build
cmake ..
make
经过上述命令,完成编译工作。
3.运行
在build文件夹下,运行
sudo ./testa
便可运行。
要是使用catkin_make方式进行编译的,去devel文件夹下面的lib里面去寻找相应的二进制执行文件去执行。
下载地址
自己的练习示例文件:https://download.csdn.net/download/qq_19280295/86721754