MATLAB使用mex调用C++ —— mexFunction函数及格式

MATLAB使用mex调用C++ —— mexFunction函数及格式

网上关于这个函数如何编写如何使用写的非常杂乱,不断尝试才能碰巧成功。
淋过雨给大家撑把伞,把我在编写mex函数时遇到的坑和解决方式都罗列一下。

编写和运行步骤

  • 一.准备工作及配置
  • 二.mex函数格式及编写
  • 三.在MATLAB中使用mex函数

一.准备工作及配置

1.安装MinGW-w64使用MEX调用C/C++

还没有做好准备工作的小伙伴可以去看我的这篇博客哈!

https://blog.csdn.net/Antoi_nette/article/details/137891285

2.VScode配置

使用的C++扩展:

  • C/C++
  • Code Runner
    步骤:
  • 在vscode中按Ctrl+Shift+P输入configuration
  • 打开c_cpp_properties.json,在includePath字段中添加待添加的SDK或者库的头文件路径。
  • 具体路径是matlab所在路径的/extern/include
    注意:路径可能会被覆盖,具体原因我也不清楚,我的解决方法是删除了多余的扩展,并且加入了一段browse。记得确保写了,逗号。
    "browse": {
        "path": [
          "F:/matlab/R2021b/extern/include"
        ],
        "databaseFilename": ""
      },

如图所示:
在这里插入图片描述

至此准备工作就差不多了!接下来就是主菜了!


二.mex函数格式及编写

编写mex函数主要分为两部分,一部分是mexFunction函数,一部分是主体函数。

  • mexFunction函数的用处是进行matlab和C++的编译。
  • 主体函数则是我们需要调用的C++函数。

在这里详细介绍一个坑(?)——那就是函数命名。

  • CPP文件名自拟。
  • mexFunction函数的名字不可更改。
  • 主体函数名自拟。
    CPP文件名和主体函数名可以不一致,但是最好保持一致,这样方便在matlab使用函数的时候不会搞错。
    如果cpp文件名和主体函数名不一致,那么,在matlab中使用的是cpp文件名。
    例如:

文件名叫mex_function.cpp
mex_function.cpp文件中包含了mexFunction(...)函数和function(...)主体函数。

那么,matlab命令为:mex mex_function.cpp

1.头文件

mexFunciton函数需要引用头文件:mex.hmatrix.h

#include "mex.h"
#include "matrix.h"

其中,mex.h是必须引用的,matrix.h看需要,如果需要获取矩阵维度就需要引用这个头文件。这两个头文件都保存在1.2中提到的matlab所在路径的/extern/include中。
直接都引用了得了,小孩子才做选择,大人allin。

2.mexFunction函数

mexFunction函数的格式如下,四个参数分别对应了matlab的左位输出和右位输入。
n代表数量,p代表指针,l/r代表左/右。

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
/**
 * nlhs:函数左侧,输出参数数目
 * plhs:函数左侧,指向输出参数的指针 
 * nrhs:函数右侧,输入参数数目
 * prhs:函数右侧,指向输入参数的指针
*/
}

2.1.mexFunction函数输入编写

mexFunction函数是通过指针来指向输入输出矩阵的,因此我们需要在函数中定义指向指针并获取所需的数据。按需要设置指针的数量。

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
    double *r,*t;   //指向输入矩阵的指针
    int nr,nt,k;    //获取输入矩阵的维数


//创建指向输入矩阵r&t的指针,假设输入矩阵有两个。
    r = mxGetPr(prhs[0]);   //指向第一个输入矩阵r
    t = mxGetPr(prhs[1]);   //指向第二个输入矩阵t

//获取输入矩阵r的维数
    nr = mxGetM(prhs[0]);   //返回指定数组中的行数
    k = mxGetN(prhs[0]);    //返回指定数组中的列数

//获取输入矩阵t的维数
    nt = mxGetM(prhs[1]);
//对矩阵t的列数进行判断
    if(mxGetN(prhs[1])!=k){
        mexErrMsgIdAndTxt( "MATLAB:dtw_c:dimNotMatch",
                    "dtw_c: Dimensions of input s and t must match.");
    }
}

有人会问了,那nrhs和nlhs的作用是什么?
最简单的用处:判断输入参数是否正确的限制条件。
例如,如果我们输入参数有且只有2或3个,输出只有一个,那么就可以如下编写错误信息。

//invalid Case
    if(nrhs!=2&&nrhs!=3){
        mexErrMsgIdAndTxt( "MATLAB:dtw_c:invalidNumInputs",
                "Two or three inputs required.");
    }
    if(nlhs>1){
        mexErrMsgIdAndTxt( "MATLAB:dtw_c:invalidNumOutputs",
                "对应function名字: One output required.");
    }

这样就可以帮助我们快速找到错误信息和对应的函数名字(如果存在多个函数)。

2.3.mexFunction函数主体编写

一般来说,直接使用主体函数就行,将主体函数分开写有利于代码修改。主体函数就按需正常编写就可以了。
如果只有一个结果,可以直接定义输出指针(参考2.4.case1)指向结果。
如果有多个结果,可以定义一个结构体或者什么都行,存储,然后挨个赋值给plhs。
例如:

// 调用主体函数function 
  Result result = function(...);   //定义结构体存储多个输出

2.4.mexFunction函数输出编写

输出和输入类似。创建一个指针指向输出然后存放。不同的是,我们需要定义每一个参数的行列数。
例如:

//定义plhs[0]存放的结果; 参数1-行数, 参数2-列数。

//case1:假设此处存放简单的double类型。
    plhs[0] = mxCreateDoubleMatrix( 1, 1, mxREAL);  
//创建指向plhs[0]矩阵的指针
    double *dp0 = mxGetPr(plhs[0]);
//结果赋值
    dp0[0] = function(...);

//case2: 假设此处存放一个vector<double>数据。
//获取数据的行数
    int row = result.size();//假设result是主体函数的结果

//定义plhs[1]存放的结果; 参数1-行数, 参数2-列数。
    plhs[1] = mxCreateDoubleMatrix(Size, 1, mxREAL);
//创建指向plhs[1]矩阵的指针   
    double *dp1 = mxGetPr(plhs[1]);
    for (int i = 0; i < row; ++i) {
        dp1[i] = result[i];
    }

还有更多输出就以此类推。


三.在MATLAB中使用mex函数

指令:mex CPP文件名
然后就可以直接使用了!
over!庆祝!

  • 25
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值