创建 C++ MEX 源文件
下面说明如何创建基本的 C++ MEX 函数。此函数只向输入数组的每个元素添加偏移量,以演示基本的输入和输出。有关创建 MEX 函数源代码的更详细讨论,请参阅 Structure of C++ MEX Function和相关主题。
创建源文件
使用您的编辑器,创建扩展名为 .cpp
的文件,并添加注释说明。例如,MyMEXFunction.cpp
。
/* MyMEXFunction
* c = MyMEXFunction(a,b);
* Adds offset argument a to each element of double array b and
* returns the modified array c.
*/
添加所需的头文件
对于 C++ MEX 函数,添加下列头文件。
/* MyMEXFunction
* c = MyMEXFunction(a,b);
* Adds offset argument a to each element of double array b and
* returns the modified array c.
*/
#include "mex.hpp"
#include "mexAdapter.hpp"
使用便利定义
(可选)为 matlab::data
指定命名空间并定义其他便利。
/* MyMEXFunction * c = MyMEXFunction(a,b); * Adds offset argument a to each element of double array b and * returns the modified array c. */ #include "mex.hpp" #include "mexAdapter.hpp" using namespace matlab::data; using matlab::mex::ArgumentList;
定义 MexFunction 类
所有 C++ MEX 函数都作为名为 MexFunction
的类来实现。此类必须派生自 matlab::mex::Function
。
/* MyMEXFunction * c = MyMEXFunction(a,b); * Adds offset argument a to each element of double array b and * returns the modified array c. */ #include "mex.hpp" #include "mexAdapter.hpp" using namespace matlab::data; using matlab::mex::ArgumentList; class MexFunction : public matlab::mex::Function { };
定义 operator()
所有 MexFunction
类必须覆盖函数调用运算符 operator()
,以接受 matlab::mex::ArgumentList
类型的两个参量。这些参量包含输入和输出。
/* MyMEXFunction
* c = MyMEXFunction(a,b);
* Adds offset argument a to each element of double array b and
* returns the modified array c.
*/
#include "mex.hpp"
#include "mexAdapter.hpp"
using namespace matlab::data;
using matlab::mex::ArgumentList;
class MexFunction : public matlab::mex::Function {
public:
void operator()(ArgumentList outputs, ArgumentList inputs) {
}
};
添加成员函数以检查参量
进行测试,以查看参量的类型和大小是否正确。如果测试失败,请调用 MATLAB® error
函数。
/* MyMEXFunction
* c = MyMEXFunction(a,b);
* Adds offset argument a to each element of double array b and
* returns the modified array c.
*/
#include "mex.hpp"
#include "mexAdapter.hpp"
using namespace matlab::data;
using matlab::mex::ArgumentList;
class MexFunction : public matlab::mex::Function {
public:
void operator()(ArgumentList outputs, ArgumentList inputs) {
}
void checkArguments(ArgumentList outputs, ArgumentList inputs) {
// Get pointer to engine
std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
// Get array factory
ArrayFactory factory;
// Check offset argument: First input must be scalar double
if (inputs[0].getType() != ArrayType::DOUBLE ||
inputs[0].getNumberOfElements() != 1)
{
matlabPtr->feval(u"error",
0,
std::vector<Array>({ factory.createScalar("First input must be scalar double") }));
}
// Check array argument: Second input must be double array
if (inputs[1].getType() != ArrayType::DOUBLE)
{
matlabPtr->feval(u"error",
0,
std::vector<Array>({ factory.createScalar("Input must be double array") }));
}
// Check number of outputs
if (outputs.size() > 1)
{
matlabPtr->feval(u"error",
0,
std::vector<Array>({ factory.createScalar("Only one output is returned") }));
}
}
};
实现计算
获取标量偏移量,并将其赋给 const
double
。获取输入数组,并将其移至 matlab::data::TypedArray<double>
来处理该数组。将偏移量添加到数组中的每个元素,并将修改后的数组赋给输出变量。
/* MyMEXFunction
* c = MyMEXFunction(a,b);
* Adds offset argument a to each element of double array b and
* returns the modified array c.
*/
#include "mex.hpp"
#include "mexAdapter.hpp"
using namespace matlab::data;
using matlab::mex::ArgumentList;
class MexFunction : public matlab::mex::Function {
public:
void operator()(ArgumentList outputs, ArgumentList inputs) {
checkArguments(outputs, inputs);
const double offSet = inputs[0][0];
TypedArray<double> doubleArray = std::move(inputs[1]);
for (auto& elem : doubleArray) {
elem += offSet;
}
outputs[0] = doubleArray;
}
void checkArguments(ArgumentList outputs, ArgumentList inputs) {
// Get pointer to engine
std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
// Get array factory
ArrayFactory factory;
// Check offset argument: First input must be scalar double
if (inputs[0].getType() != ArrayType::DOUBLE ||
inputs[0].getType() == ArrayType::COMPLEX_DOUBLE ||
inputs[0].getNumberOfElements() != 1)
{
matlabPtr->feval(u"error",
0,
std::vector<Array>({ factory.createScalar("First input must be scalar double") }));
}
// Check array argument: Second input must be double array
if (inputs[1].getType() != ArrayType::DOUBLE ||
inputs[1].getType() == ArrayType::COMPLEX_DOUBLE)
{
matlabPtr->feval(u"error",
0,
std::vector<Array>({ factory.createScalar("Input must be double array") }));
}
// Check number of outputs
if (outputs.size() > 1) {
matlabPtr->feval(u"error",
0,
std::vector<Array>({ factory.createScalar("Only one output is returned") }));
}
}
};
设置和编译
安装支持的编译器后,使用 mex
命令编译您的 MEX 函数。
mex -setup c++ mex MyMEXFunction.cpp
有关编译 MEX 函数的详细信息,请参阅编译 C++ MEX 程序。
调用 MEX 函数
从 MATLAB 调用您的 MEX 函数。
b = MyMEXFunction(11.5, rand(1000));
另请参阅
mex
| matlab::mex::Function
| matlab::mex::ArgumentList