创建 C 源 MEX 文件 arrayProduct.c
此示例说明如何编写 MEX 文件,以在 MATLAB® 中使用在 C Matrix API 中定义的 MATLAB 数组调用 C 函数 arrayProduct
。您可以在此处查看完整的源文件。
要使用此示例,您需要:
能够编写 C 或 C++ 源代码。您使用 MATLAB 编辑器创建这些文件。
MATLAB 支持的编译器。有关支持的编译器的最新列表,请参阅支持和兼容的编译器网站。
C Matrix API 和 C 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 文件的输入和输出参数
使用 nrhs
和 nlhs
参量验证 MEX 文件输入和输出参量的数量。
要检查两个输入参量 multiplier
和 inMatrix
,请使用以下代码。
if(nrhs != 2) { mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs", "Two inputs required."); }
使用以下代码检查一个输出参量,即乘积 outMatrix
。
if(nlhs != 1) { mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs", "One output required."); }
使用 plhs
和 prhs
参量验证参量类型。以下代码将验证 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
。将变量 n
和 i
的 int
声明替换为 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 Data API for C++ 的 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)
另请参阅
mex
| mexFunction
| mxCreateDoubleMatrix