vs2013 cpp qt调用matlab M文件,典型复杂接口示例

5 篇文章 0 订阅

前一个示例很简单,如下链接:
vs2013 cpp qt 直接调用matlab m文件_matlab,c++_weixin_43172531的博客-CSDN博客
https://blog.csdn.net/weixin_43172531/article/details/105570403
示例中,只是一个add函数,参数只是两个整数,返回值也只一个。

典型的复杂接口,包含两个输入参数(一个为double vector,一个为int参数值),两个输出参数(一个为double vector,一个为string错误信息)
示例是一个处理一维double vector的均值算法,int参数为窗口大小,一般窗口为3.
相关m dll调用方式,见以下链接:
win7 x64下,matlab2016的均值滤波m文件转成vs2013 cpp dll,cpp调用实例_人工智能_weixin_43172531的博客-CSDN博客
https://blog.csdn.net/weixin_43172531/article/details/104034978

matlab均值算法的M文件直接调用方式如下:


bool data_process::junzhi_M(std::string &error_msg,
    double_vec &dVecOut, double_vec &dVecIn, const int iWinSize)
{
    //function [OutResult,error_msg] =junzhi(double_vec,win_size)
    //iOut一般为1。此处加了error_msg,所以为2.
    //dVecIn输入参数一般为浮点数数组
    //iWinSize均值滤波的窗口大小,一般为奇数3、5、7...
    try
    {
        //初始化matlab引擎,只有第一次初始化比较慢
        if (!initialize_matlab_M())
        {
            return false;
        } 
        //double vector参数传值
        mxArray *double_vec = mxCreateDoubleMatrix(1, dVecIn.size(), mxREAL);
        if (double_vec)
        {
            memcpy((void *)mxGetPr(double_vec), (void *)(&(dVecIn[0])), sizeof(double)*dVecIn.size());
            engPutVariable(p_engine_, "double_vec", double_vec);
        }
        else
        {
            GuiLog("[ERROR]mxCreateDoubleMatrix(...) error.");
            engClose(p_engine_);
            return false;
        }
        //int参数传值
        mxArray *win_size = mxCreateNumericMatrix(1, 1, mxINT32_CLASS, mxREAL);
        if (win_size)
        {
            memcpy((void *)mxGetPr(win_size), (void *)(&(iWinSize)), sizeof(int));
            engPutVariable(p_engine_, "win_size", win_size);
        }
        else
        {
            GuiLog("[ERROR]mxCreateNumericMatrix(...) error.");
            engClose(p_engine_);
            return false;
        }
        //
        engEvalString(p_engine_, "[OutResult,error_msg] =junzhi(double_vec,win_size)");//matlab设置路径,把存储本地m文件的路径添加到默认搜索路径中。
        //获得返回值
        mxArray *OutResult = engGetVariable(p_engine_, "OutResult");
        mxArray *error_msg = engGetVariable(p_engine_, "error_msg");
        if (NULL == OutResult || NULL == error_msg)
        {
            if (OutResult)
            {
                mxDestroyArray(OutResult);
            }
            if (error_msg)
            {
                mxDestroyArray(error_msg);
            }
            GuiLog("[ERROR]engGetVariable(ep, ...) error.");
            engClose(p_engine_);
            return false;
        }
        //double vector返回值
        size_t M = mxGetM(OutResult);//1,行
        size_t N = mxGetN(OutResult);//vector size 列
        dVecOut.resize(M * N);//dVecOut输出参数与输入大小一样
        memcpy((void *)(&(dVecOut[0])), (void *)mxGetPr(OutResult), sizeof(double) * M * N);
        //错误信息返回值
        std::wstring error_msg_wstr;
        if (mxIsChar(error_msg))
        {
            error_msg_wstr = mxGetChars(error_msg);//错误信息,null表示无错误
        }
        std::string error_msg_str = CodePageInfor::wstring2string(error_msg_wstr);        
        //内存释放
        mxDestroyArray(OutResult);
        mxDestroyArray(error_msg);
        //关闭引擎
        //terminate_matlab_M();//全局关闭一次
        //错误信息判断
        if (error_msg_str != "null")
        {
            GuiLog(error_msg_str);
            return false;
        }
    }
    catch (std::exception &e)
    {
        GuiLog("[ERROR]data_process::junzhi_m error.");
        GuiLog(CodePageInfor::LocalToUtf8(e.what()));
        return false;
    }
    return true;
}

初始化函数,每个算法函数都初始化,实际只初始化一次

bool data_process::initialize_matlab_M()
{
    if (!b_init_matlab_M)
    {
        //初始化matlab引擎,只有第一次初始化比较慢
        p_engine_ = engOpen(NULL);
        if (NULL == p_engine_)
        {
            GuiLog("[ERROR]engOpen(NULL) error. Matlab is not running?");
            return false;
        }
        else
        {
            GuiLog("engOpen ok.");
        }
        //初始化,没有此句mxCreateDoubleMatrix返回值为NULL。只能初始化一次。
        if (!mclInitializeApplication(NULL, 0))
        {
            GuiLog("[ERROR]mclInitializeApplication(NULL, 0) error.");
            engClose(p_engine_);
            p_engine_ = NULL;
            return false;
        }
        else
        {
            GuiLog("mclInitializeApplication ok.");
        }
        b_init_matlab_M = true;
    }
    return true;
}

释放引擎的代码,程序退出时执行一次

bool data_process::terminate_matlab_M()
{
    if (b_init_matlab_M)
    {
        if (!mclTerminateApplication())
        {
            GuiLog("mclTerminateApplication error.");
        }
        else
        {
            GuiLog("mclTerminateApplication ok.");
        }
        if (p_engine_)
        {
            engClose(p_engine_);
            p_engine_ = NULL;
        }
        b_init_matlab_M = false;
    }
    return true;
}

接口定义

public:
    static bool terminate_matlab_M(); /**< matlab M引擎析构*/    
    static bool junzhi_M(std::string &error_msg,
        double_vec &dVecOut, double_vec &dVecIn, const int iWinSize); /**< 均值滤波,matlab M版本*/
private:
    static bool b_init_matlab_M;
    static Engine *p_engine_;
    static bool initialize_matlab_M(); /**< matlab M引擎相关初始化*/

头文件包含
h文件中如下定义

#ifndef Engine
struct engine;
typedef struct engine Engine;
#endif // !Engine

cpp文件中包含如下

#include "engine.h"

测试代码如下:

void db_view::m_junzhi_example_M()
{
    GuiLogRunFunc();
    //直接调用M文件的测试代码
    yf::data_node data_temp;
    yf::mem_data *p_ori_data = data_temp.get_mem_data_original(true);
    p_ori_data->load_file(yf::global_data::get_data_folder() + "/1.data");
    yf::mem_data *p_aft_data = data_temp.get_mem_data_after(true);
    std::string error_msg;
    bool b = yf::data_process::junzhi_M(error_msg, p_aft_data->val_vec_, p_ori_data->val_vec_, 3);
    p_aft_data->id_vec_ = p_ori_data->id_vec_;
    yf::view_node view_temp("2d_graph");
    b = ShowDataInQwt(&data_temp, &view_temp, ui_.qwtPlot);
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值