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<QLabel>
#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"<<std::endl;
    }
     mwArray mydirpath(temp_dirpath),hello;
     aaa(1,hello,mydirpath);
     char str[50];
     strcat(str, hello.ToString());
     QLabel *test = new QLabel(this);

    test->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"<<std::endl;
    }
     mxArray  *mychar = mxCreateString(temp_dirpath);
     mlfAaa(mychar);
     aaaTerminate();
     aaaPrintStackTrace();
     mclTerminateApplication();
    /**C**/

主要问题汇集:
  • 程序打包过程中出错:查看logfile文件的错误信息,大部分是gcc编译器的问题。
  • 使用qtcreate 运行程序出现:xxxxx/glnxa64/libmat.so: shared object not open
    QT版本高于matlab版本所要求的QT版本所导致。解决办法请看第三步
  • 如提示需要安装MCR,则在matlab 命令行中输入mcrinstaller,如有则会给出安装包的路径mcrinstaller.zip,根据路径解压之后,进入目录执行./install即可。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,122评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,070评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,491评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,636评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,676评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,541评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,292评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,211评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,655评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,846评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,965评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,684评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,295评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,894评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,012评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,126评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,914评论 2 355

推荐阅读更多精彩内容