linux--QT create(C++ or C)调用matlab代码

  • 在实际项目中,为了更快的验证不同算法的性能优劣,由于matlab独特的优势(矩阵运算,弱类型,可视化等等),我们通常会先使用matlab验证。
  • 验证完成之后,由于实时性问题,通常需要我们转成c,c++,java等语言用于实际工程项目中。目前matlab转c或者c++大致有三种方式:
    1.通过第三方库如eigen,原生态转成c++
    2.通过matlab coder将matlab文件直接转成c++
    3.通过matlab compiler将matlab函数打包成.h和动态链接库,在c++调用。
  • 以上三种方式的实时性,理论上第一种方式实时性最高,第三种方式最低,第二种其次。但是在开发的周期和效率方面,则相反,第一种方式开发周期最长,第三种最短。
  • 如果对实时要求较高,建议使用第一种方式,如果对实时性要求不高(比如离线数据处理等),建议使用第三种方式。
  • 本文主要讲述在linux环境下如何使用第三种方式:通过matlab compiler将matlab函数打包成.h和动态链接库,在c++调用。

下面我们开始

  • 第一步:下载matlab。下载好linux下的matlab,随便哪个版本都OK,建议下载较新的,2018a 或者 2017b。
  • 第二步:确定gcc/g++的版本。确定好自己linux版本的gcc/g++版本,输入命令 gcc -vg++ -v 查看 ,然后再确定matlab版本所支持的gcc版本,根据自己已安装的matlab版本,自行下载查看。尽量保证matlab gcc 版本和 linux的gcc版本一致,至少不能低于所要求的版本!如果版本不一致或者有系统有多个版本,请参照这里和这里。如果出现以下错误请参照这里.:

Err http://archive.ubuntu.com yakkety/main amd64 Packages 404 Not Found

  • 第三步:确定QT版本。进入Matlab安装目录,运行命令sudo find . -name libQt*,通过动态链接库查看当前matlab所支持的最高QT版本。如果出现的都是libQtxxx.so.5.5.x,说明matlab所支持的最高QT版本为QT5.5,QT下载地址,如果已经下载了qtcreat,那么请先选择版本后然后进入single下载,然后按照这里操作,安装成功之后将新的QT版本路径加载到QTcreate中去即可,并在项目中切换即可。

    image.png

    image.png

    image.png

  • 第四步:编写一个简单的matlab程序,aaa.m文件:

function [hello] = aaa(dir_name)
hello = dir_name;

end

  • 然后在command window输入:deploytool 选择LIbrary Compiler ,如下图所示:

    image.png

  • 进入Matlab Compiler界面,选择c++ share Library,再点击+,选择aaa.m文件

    image.png

    image.png

  • 然后再点击package打包,设置prj文件的路径之后,就会出现如下图所示的界面。

    image.png

  • 如果出现以下界面说明打包成功,注意:如果gcc版本不一致会给出警告,可以点击logfile文件查看信息,另外由于动态链接库的必须使用lib开头(正常应该是libaaa.so),这里是(aaa.so),所以也会给出警告。后续导入到QT pro进去之前需要将aaa.so重命名为libaaa.so.

    image.png

  • 进入打包好的文件夹,如下图


    image.png

我们只要for_redistribution_files_only目录下面的.h .so文件即可。记得把aaa.so重命名为libaaa.so

  • 第五步:在QT create中调用c++。打开qtcreate新建一个application应用.


    image.png
  • 在pro文件中添加打包aaa.h头文件和libaaa.so文件路径,另外,我们还需要加一个matlab的动态库:libmwmclmcrrt.so,以及头文件 mclmcrrt.hmclcppclass.h
    MainWindow.cpp代码如下:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include"aaa.h"
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    char temp_dirpath[150] = "hello world";
    if(!aaaInitialize())
    {
       std::cout<<" init error"<setText(QString(str));

}

MainWindow::~MainWindow()
{
    delete ui;
}

.pro文件如下:

#-------------------------------------------------
#
# Project created by QtCreator 2019-01-21T10:34:33
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = matlabtest
TEMPLATE = app

# The following define makes your compiler emit warnings if you use
# any feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0


SOURCES += \
        main.cpp \
        mainwindow.cpp

HEADERS += \
        mainwindow.h

FORMS += \
        mainwindow.ui

INCLUDEPATH +=  /home/simin/matlabPro/aaa/for_redistribution_files_only \
                /usr/local/MATLAB/MATLAB_Runtime/v93/extern/include/


LIBS += \
        -L/home/simin/matlabPro/function_test/for_redistribution_files_only \
        -L/home/simin/matlabPro/aaa/for_redistribution_files_only \
        -L/usr/local/MATLAB/MATLAB_Runtime/v93/runtime/glnxa64 \
        -lmwmclmcrrt -laaa

编译运行结果:


image.png
  • 说明:aaaInitialize为aaa.h matlab提供的初始化函数(必须)。aaa.h文件里面看这两个函数
bool MW_CALL_CONV aaaInitialize(void);
extern LIB_aaa_CPP_API void MW_CALL_CONV aaa(int nargout, mwArray& hello, const mwArray& dir_name);

其中int nargout为输出参数的个数。

如果是转C语言,只需在第四步打包的时候选择C share library,然后将MainWindow.cpp对应的部分修改下面所示即可。

    /**C**/
    if(!aaaInitialize())
    {
        std::cout<<"init error"<

主要问题汇集:
  • 程序打包过程中出错:查看logfile文件的错误信息,大部分是gcc编译器的问题。
  • 使用qtcreate 运行程序出现:xxxxx/glnxa64/libmat.so: shared object not open
    QT版本高于matlab版本所要求的QT版本所导致。解决办法请看第三步
  • 如提示需要安装MCR,则在matlab 命令行中输入mcrinstaller,如有则会给出安装包的路径mcrinstaller.zip,根据路径解压之后,进入目录执行./install即可。

你可能感兴趣的:(linux--QT create(C++ or C)调用matlab代码)