• 【MPC】⑥ubuntu系统下C++程序调用MATLAB生成的.so动态库文件


    前面几期文章已经介绍: 1)利用MATLAB编写quadprog函数程序; 2)利用MATLAB工具箱生成.so动态库文件;
    3)MATLAB函数dll库生成与win平台调用; 4)Linux端.so动态库文件Vscode调用。
    本篇文章主要介绍,Linux系统使用C++程序调用MATLAB生成的.so动态库文件的方法。

    一、环境配置

    在这里插入图片描述
    环境配置部分可以参考:库文件–>for_testing–>readme.txt

    (一)安装MATLAB Runtime插件

    1、MATLAB Runtime插件介绍

    MCR之前是 matlab component runtime的缩写,后更名为 matlab compiler runtime。MCR实际上是一组独立的共享库,也即是常说的动态连接库,所起的作用是使得你可以执行编译过的matlab文件,与matlab提供的另外两个库----数学库和图形库不同之处在于它支持matlab语言所有的特性,而不仅仅是数学计算和图形功能。换句话说他的作用就是给编译后的matlab文件执行提供一个环境。MCR 是用于执行已编译 MATLAB 代码的引擎。因此,当已编译的应用程序运行时,有时会在 MCR 初始化时出现延迟。

    2、MATLAB Runtime安装方法

    参考: https://blog.csdn.net/m0_70509260/article/details/124564051
    https://blog.csdn.net/qq_41990294/article/details/109154801

    在下载软件的时候,需要下载对应版本的MATLAB Runtime,可以参考readme.txt文件查看依赖的MCR的版本号。

    3、MATLAB Runtime安装步骤

    unzip MATLAB_Runtime_R2021a_glnxa64.zip
    sudo ./install
    
    • 1
    • 2

    之后将进入图像化安装界面:
    在这里插入图片描述

    (二)库文件打包

    Files to Package
    ================
    -libC_QUADPROG.so
    -libC_QUADPROG.h
    -MCRInstaller.zip //MATLAB_Runtime_R2021a_Update_6_glnxa64.zip
    
    • 1
    • 2
    • 3
    • 4
    • 5

    对动态库打包的时候,需要配置以下三个文件。libC_QUADPROG.so是动态链接库的库文件,libC_QUADPROG.h是动态链接库的头文件。MCRInstaller.zip 是MATLAB Runtime的安装包文件

    (三)配置环境变量

    linux系统具有多种环境变量配置方法

    参考:https://blog.csdn.net/qdPython/article/details/125430322

    典型方法1:

    sudo gedit /etc/profile
    source /etc/profile
    
    • 1
    • 2

    典型方法2:

    sudo gedit ~/.bashrc
    source ~/.bashrc
    
    • 1
    • 2

    需要对照readme.txt配置环境变量
    在这里插入图片描述

    按照我的安装路径,MR应该代替MATLAB Runtime的目录:/usr/local/MATLAB/MATLAB_Runtime
    
    • 1

    XAPPLRESDIR
    模板:MR/v910/X11/app-defaults
    :/usr/local/MATLAB/MATLAB_Runtime/v910/X11/app-defaults
    此处出现错误:按照readme.txt该路径没有app-defaults文件,可以自行搜索文件夹
    在这里插入图片描述
    LD_LIBRARY_PATH
    模板:MR/v910/runtime/glnxa64:MR/v910/bin/glnxa64:MR/v910/sys/os/glnxa64:MR/v910/sys/opengl/lib/glnxa64
    If it is defined, set it to the following:
    ${LD_LIBRARY_PATH}:MR/v910/runtime/glnxa64:MR/v910/bin/glnxa64:MR/v910/sys/os/glnxa64:MR/v910/sys/opengl/lib/glnxa64

    //参考:
    # export XAPPLRESDIR=/usr/share/X11/app-defaults
    export XAPPLRESDIR=/etc/X11/app-defaults
    # export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/MATLAB/MATLAB_Compiler_Runtime/v91/runtime/glnxa64:/usr/local/MATLAB/MATLAB_Compiler_Runtime/v91/bin/glnxa64:/usr/local/MATLAB/MATLAB_Compiler_Runtime/v91/sys/os/glnxa64:/usr/local/MATLAB/MATLAB_Compiler_Runtime/v91/sys/opengl/lib/glnxa64
    export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/MATLAB/MATLAB_Runtime/v910/runtime/glnxa64:/usr/local/MATLAB/MATLAB_Runtime/v910/bin/glnxa64:/usr/local/MATLAB/MATLAB_Runtime/v910/sys/os/glnxa64:/usr/local/MATLAB/MATLAB_Runtime/v910/sys/opengl/lib/glnxa64
    
    • 1
    • 2
    • 3
    • 4
    • 5

    二、测试代码

    (一)main.cpp

    #include 
    #include "libC_QUADPROG.h"
    #include "mclcppclass.h"
    #include 
    using namespace std;
    int main()
    {
        
        //初始化DLL动态连接文件
        mclmcrInitialize();
        // 鉴定Matlab外部调用环境设置是否正确.
        if (!mclInitializeApplication(NULL, 0)) {
            cout << "error1" << endl;
            return -1;
        }
        
        libC_QUADPROGInitialize();
        if (!libC_QUADPROGInitialize()) {
            cout << "error2" << endl;
            return -1;
        }
        
        double g[3][1] = { {-7},{-12},{-15} };
        double A[1][3] = { 1, 1, 1 };
        double b[1] = { 1 };
        double lb[3][1] = { {-10},{-10},{-10} };
        double ub[3][1] = { {10},{10},{10} };
        //创建
        mxArray* Input_H = mxCreateDoubleMatrix(3, 3, mxREAL);
        mxArray* Input_g = mxCreateDoubleMatrix(3, 1, mxREAL);
        mxArray* Input_A = mxCreateDoubleMatrix(1, 3, mxREAL);
        mxArray* Input_b = mxCreateDoubleMatrix(1, 1, mxREAL);
        mxArray* Input_lb = mxCreateDoubleMatrix(3, 1, mxREAL);
        mxArray* Input_ub = mxCreateDoubleMatrix(3, 1, mxREAL);
        mxArray* Output_x = mxCreateDoubleMatrix(1, 3, mxREAL);
        double * result;
        //赋值
        memcpy(mxGetPr(Input_g), (void*)g, sizeof(g));
        memcpy(mxGetPr(Input_A), (void*)A, sizeof(A));
        memcpy(mxGetPr(Input_b), (void*)b, sizeof(b));
        memcpy(mxGetPr(Input_lb), (void*)lb, sizeof(lb));
        memcpy(mxGetPr(Input_ub), (void*)ub, sizeof(ub));
        //运算
        double H[3][3] = { {-1,0,0},{0,-2,0},{0,0,-3} };
        memcpy(mxGetPr(Input_H), (void*)H, sizeof(H));
        mxArray* Input[6] = { Input_H, Input_g, Input_A, Input_b, Input_lb, Input_ub };
        mxArray* Output[1];
        mlxC_QUADPROG(1, Output, 6, Input);
        Output_x = Output[0];
    
        //输出测试
        result= mxGetPr(Output_x);
        for(int i=0;i<3;i++)
            cout<<result[i]<<endl;
    
        //释放空间
        mxDestroyArray(Input_H);
        mxDestroyArray(Input_g);
        mxDestroyArray(Input_A);
        mxDestroyArray(Input_b);
        mxDestroyArray(Input_lb);
        mxDestroyArray(Input_ub);
        mxDestroyArray(Output_x);
    
        libC_QUADPROGTerminate(); //结束DLL库
        mclTerminateApplication();  
        pause();
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69

    (二)task.json

    {
        "tasks": [
            {
                "type": "cppbuild",
                "label": "C/C++: g++ build active file",
                "command": "/usr/bin/g++",
                "args": [
                    "-g","-std=c++11",
                    "${workspaceFolder}/main.cpp",
                    "-o",
                    "${workspaceFolder}/build/${fileBasenameNoExtension}",  //生成的包一定要是lib+包名+.so的形式
                    "-I", "${workspaceFolder}",
                    "-I", "/usr/local/MATLAB/MATLAB_Runtime/v910/extern/include",
                    "-L", "${workspaceFolder}",
                    "-L", "/usr/local/MATLAB/MATLAB_Runtime/v910/runtime/glnxa64",
                    "-l", "mwmclmcrrt",
                    "-l", "C_QUADPROG"
                ],
                "options": {
                    "cwd": "${workspaceFolder}"
                },
                "problemMatcher": [
                    "$gcc"
                ],
                "group": {
                    "kind": "build",
                    "isDefault": true
                },
                "detail": "Task generated by Debugger."
            }
        ],
        "version": "2.0.0"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    (三)launch.json

    {
        // 使用 IntelliSense 了解相关属性。 
        // 悬停以查看现有属性的描述。
        // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
        "version": "0.2.0",
        "configurations": [
            {
                "name": "g++ - 生成和调试活动文件",
                "type": "cppdbg",
                "request": "launch",    
                "program": "${workspaceFolder}/build/${fileBasenameNoExtension}",
                "args": [],
                "stopAtEntry": false,
                "cwd": "${workspaceFolder}",
                "environment": [],
                "externalConsole": false,
                "MIMode": "gdb",
                "setupCommands": [
                    {
                        "description": "为 gdb 启用整齐打印",
                        "text": "-enable-pretty-printing",
                        "ignoreFailures": true
                    }
                ],
                "preLaunchTask": "C/C++: g++ build active file",
                "miDebuggerPath": "/usr/bin/gdb"
            }
        ]
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    (四)c_cpp_properties.json

    {
        "configurations": [
            {
                "name": "Linux",
                "includePath": [
                    "${workspaceFolder}",
                    "/usr/local/MATLAB/MATLAB_Runtime/v910/extern/include"
                ],
                "defines": [],
                "compilerPath": "/usr/bin/g++",
                "cStandard": "c11",
                "cppStandard": "c++11",
                "intelliSenseMode": "gcc-x64"
            }
        ],
        "version": 4
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    三、编译条件

    参考:https://cloud.tencent.com/developer/article/1016567

    编译条件包含三个部分:包含目录、库目录、动态链接库

    # 参考
    g++ - c test.cpp -I/usr/local/MATLAB/R2016b/extern/include/ -o test.o
    g++ -o testApp test.o -L/home/liupeng/Desktop/test-L/usr/local/MATLAB/R2016b/runtime/glnxa64  -lmwmclmcrrt  -L/home/liupeng/Desktop/test-lMypr
    
    • 1
    • 2
    • 3

    (一)MATLAB编译依赖

    • 必须添加:#include “C_QUADPROG.h”,可能需要添加#include “mclcppclass.h”
      网上经常添加的头文件,例如:#include “mclmcrrt.h”,已经包含在MCC生成的头文件中了;#include “mclmcr.h”,也包含在mcc文件中;#include "matrix.h"定义在mclmcrrt.h头文件中。
    • 必须添加的库文件:#include “mclcppclass.h”

    (二)动态连接库编译依赖

    • 包含目录、库目录:都是当前目录
    • 动态链接库运行时搜索目录:可以设置环境变量进行配置
      需要将MCC生成的动态库复制到matlab的动态库搜索路径或者添加新的环境变量,/usr/local/MATLAB/MATLAB_Runtime/v910/runtime/glnxa64

    四、实验结果

    在这里插入图片描述

    参考资料:
    (1)Ubuntu下用c++调用自己编写的matlab函数:https://blog.csdn.net/qq_41990294/article/details/109154801
    (2)ubuntu系统下C++调用matlab程序的方法详解:https://www.zhangshengrong.com/p/Z9a2jLDaVk/
    (3)Linux下C调用matlab生成的动态链接库之环境配置:https://blog.csdn.net/Ljy233super/article/details/109513848

  • 相关阅读:
    电脑蓝牙在哪里打开?1分钟轻松打开蓝牙!
    什么是NLP-自然语言处理
    【视觉SLAM入门】9.1 建图1---SLAM任务,稠密地图构建,立体视觉,RGBD,八叉树,点云地图等各种不同地图
    canvas 系列学习笔记四《绘制文本》
    tensorflow数据类型转换
    一文详解 Okio 输入输出流
    机器学习基础篇(4)滤波器
    总结的HTTP比较详细的知识
    【Docker】Docker-compose及Consul多容器编排工具
    javaweb(servlet)+jsp+Mysql实现的简单相册管理系统(功能包含登录、管理首页、添加图片、分类管理、修改密码、图片详情等)
  • 原文地址:https://blog.csdn.net/zeye5731/article/details/126006022