本页对应的英文页面已更新,但尚未翻译。 若要查看最新内容,请点击此处访问英文页面。

创建 C 源 MEX 文件

此示例说明如何编写 MEX 文件,以在 MATLAB® 中使用在 C 矩阵 API 中定义的 MATLAB 数组调用 C 函数 arrayProduct。您可以在此处查看完整的源文件。

要使用此示例,您需要:

  • 能够编写 C 或 C++ 源代码。您使用 MATLAB 编辑器创建这些文件。

  • MATLAB 支持的编译器。有关支持的编译器的最新列表,请参阅支持和兼容的编译器网站。

  • C 矩阵 APIC MEX API 中的函数。

  • mex 编译脚本。

如果您要使用自己的 C 开发环境,请参阅Custom Build with MEX Script Options了解详细信息。

C 函数 arrayProduct

以下代码定义 arrayProduct 函数,它将 1×n 矩阵 y 与标量值 x 相乘,并以数组 z 形式返回结果。您可以在 C++ 应用程序中使用这些相同的 C 语句。

void arrayProduct(double x, double *y, double *z, int n)
{
  int i;
  
  for (i=0; i<n; i++) {
    z[i] = x * y[i];
  }
}

创建源文件

打开 MATLAB 编辑器,创建一个文件,并在 MEX 文件中记录以下信息。

/*
 * arrayProduct.c - example in MATLAB External Interfaces
 *
 * Multiplies an input scalar (multiplier) 
 * times a 1xN matrix (inMatrix)
 * and outputs a 1xN matrix (outMatrix)
 *
 * The calling syntax is:
 *
 *		outMatrix = arrayProduct(multiplier, inMatrix)
 *
 * This is a MEX file for MATLAB.
*/

添加包含 MATLAB API 函数声明的 C/C++ 头文件 mex.h

#include "mex.h"

将文件保存在您的 MATLAB 路径(例如 c:\work)中,并将其命名为 arrayProduct.c。您的 MEX 文件名称为 arrayProduct

创建入口例程

每个 C 程序都有一个 main() 函数。MATLAB 使用入口例程 mexFunction 作为函数的入口函数。添加以下 mexFunction 代码。

/* The gateway function */
void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
/* variable declarations here */

/* code here */
}

下表描述了 mexFunction 的输入参数。

参数说明
nlhs输出(左侧)参数的数量,或 plhs 数组的大小。
plhs输出参数的数组。
nrhs输入(右侧)参数的数量,或 prhs 数组的大小。
prhs输入参数的数组。

验证 MEX 文件的输入和输出参数

使用 nrhsnlhs 参数验证 MEX 文件输入和输出参数的数量。

要检查两个输入参数 multiplierinMatrix,请使用以下代码。

if(nrhs != 2) {
    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs",
                      "Two inputs required.");
}

使用以下代码检查一个输出参数,即乘积 outMatrix

if(nlhs != 1) {
    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs",
                      "One output required.");
}

使用 plhsprhs 参数验证参数类型。以下代码将验证 multiplier(由 prhs[0] 表示)为标量。

/* make sure the first input argument is scalar */
if( !mxIsDouble(prhs[0]) || 
     mxIsComplex(prhs[0]) ||
     mxGetNumberOfElements(prhs[0]) != 1 ) {
    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notScalar",
                      "Input multiplier must be a scalar.");
}

以下代码将验证 inMatrix(由 prhs[1] 表示)为 double 类型。

if( !mxIsDouble(prhs[1]) || 
     mxIsComplex(prhs[1])) {
    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notDouble",
        "Input matrix must be type double.");
}

验证 inMatrix 为行向量。

/* check that number of rows in second input argument is 1 */
if(mxGetM(prhs[1]) != 1) {
    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notRowVector",
                      "Input must be a row vector.");
}

创建计算例程

添加 arrayProduct 代码。以下函数是您的计算例程,即用于执行您希望在 MATLAB 中使用的功能的源代码。

void arrayProduct(double x, double *y, double *z, int n)
{
  int i;
  
  for (i=0; i<n; i++) {
    z[i] = x * y[i];
  }
}

计算例程是可选的。您也可以将代码置于 mexFunction 函数块中。

编写代码以实现跨平台的灵活性

MATLAB 提供了基于平台表示整数大小值的预处理器宏 mwsize。计算例程将数组的大小声明为 int。将变量 niint 声明替换为 mwsize

void arrayProduct(double x, double *y, double *z, mwSize n)
{
  mwSize i;
  
  for (i=0; i<n; i++) {
    z[i] = x * y[i];
  }
}

声明计算例程的变量

将以下变量声明置于 mexFunction 中。

  • 声明输入参数的变量。

    double multiplier;      /* input scalar */
    double *inMatrix;       /* 1xN input matrix */
    
  • 为输入矩阵的大小声明 ncols

    mwSize ncols;           /* size of matrix */
    
  • 声明输出参数 outMatrix

    double *outMatrix;      /* output matrix */
    

稍后,将 mexFunction 参数赋给这些变量。

读取输入数据

要读取标量输入,请使用 mxGetScalar 函数。

/* get the value of the scalar input  */
multiplier = mxGetScalar(prhs[0]);

使用 mxGetDoubles 函数指向输入矩阵数据。

/* create a pointer to the real data in the input matrix  */
inMatrix = mxGetDoubles(prhs[1]);

使用 mxGetN 函数获取矩阵大小。

/* get dimensions of the input matrix */
ncols = mxGetN(prhs[1]);

准备输出数据

要创建输出参数 plhs[0],请使用 mxCreateDoubleMatrix 函数。

/* create the output matrix */
plhs[0] = mxCreateDoubleMatrix(1,ncols,mxREAL);

使用 mxGetDoubles 函数将 outMatrix 参数赋给 plhs[0]

/* get a pointer to the real data in the output matrix */
outMatrix = mxGetDoubles(plhs[0]);

执行计算

将参数传递给 arrayProduct

/* call the computational routine */
arrayProduct(multiplier,inMatrix,outMatrix,ncols);

查看完整的源文件

将源文件与位于 matlabroot/extern/examples/mexarrayProduct.c 进行比较。在编辑器中打开文件 arrayProduct.c

有关使用 MATLAB 数据 API 的 C++ MEX 文件示例,请参阅 arrayProduct.cpp。有关使用此 API 创建 MEX 文件的信息,请参阅 C++ MEX 函数

编译 MEX 函数

在 MATLAB 命令提示符下,使用 mex 命令编译该函数。

mex arrayProduct.c -R2018a

测试 MEX 函数

s = 5; 
A = [1.5, 2, 9];
B = arrayProduct(s,A)
B =
    7.5000   10.0000   45.0000 

验证 MEX 文件输入参数

最好在调用 MEX 函数之前验证 MATLAB 变量的类型。要测试输入变量 inputArg 并在必要时将其转换为 double,请使用以下代码。

s = 5; 
A = [1.5, 2, 9];
inputArg = int16(A);
if ~strcmp(class(inputArg),'double')
    inputArg = double(inputArg);
end
B = arrayProduct(s,inputArg)

另请参阅

| | | | | |

相关主题