【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

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

(二)库文件打包

Files to Package
================
-libC_QUADPROG.so
-libC_QUADPROG.h
-MCRInstaller.zip //MATLAB_Runtime_R2021a_Update_6_glnxa64.zip

对动态库打包的时候,需要配置以下三个文件。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

典型方法2:

sudo gedit ~/.bashrc
source ~/.bashrc

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

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

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

二、测试代码

(一)main.cpp

#include <iostream>
#include "libC_QUADPROG.h"
#include "mclcppclass.h"
#include <unistd.h>
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;
}

(二)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"
}

(三)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"
        }
    ]
}

(四)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
}

三、编译条件

参考: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

(一)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

  • 7
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 18
    评论
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

后厂村路蔡徐坤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值