前一个示例很简单,如下链接:
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);
}