Matlab调用C/C++函数
Matlab调用C函数
-
环境:Matlab 2016b,Vs2015
-
如果C/C++是源文件而不是库,需要借助mex的mexFunction函数建立C类型与MxArray类型转换的关系(需要用户根据自己需求转换)
-
mexFunction 函数是Matlab的入口函数 所以需要在这个函数中做类型 、矩阵之类的一些转换
基本命令
% 编译器选择
mex -setup
% 编译源文件
mex xxx.c
% 显示编译详细信息 如果出现错误会显示错误信息
mex -v -compatibleArrayDims xxx.c
% 编译完成后使用 文件名调用函数
mxGetPr
mxArray
mxCreateDoubleMatrix
mxGetPr R2018a以后不推荐使用
mxCreateDoubleMatrix 创建一个double型矩阵
基本用法
/*** add.c**/
#include <stdio.h>
#include <string.h>
#include "mex.h"
double add(double a, double b)
{
return a+b;
}
// nlhs plhs可以理解为输出参数的数量和指针,nrhs prhs理解为输出参数的数量和指针
// 具体可以看官方对 mexFunction 函数的解释和说明
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] )
{
double *a;
double b,c;
// 输出
plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL); // m*n的数组 mxREAL mxCOMPLEX 枚举类型
a = mxGetPr(plhs[0]);
// 输入
b = *(mxGetPr(prhs[0]));
c = *(mxGetPr(prhs[1]));
*a = add(b,c);
}
% 选择编译器 需要手动点击自己需要的编译器
mex -setup
% 编译
mex -v -compatibleArrayDims add.c
% 调用
add(5.1,6.3);
官方例子
- 官方例子也有学习的意义
% 复制源文件到当前工作目录
copyfile(fullfile(matlabroot,'extern','examples','mex','explore.c'),'.','f')
% 编译文件
mex explore.c
% 调用函数
a = [1 3 5];
b = [5 3 1];
A = complex(a,b);
explore(A)
参考
Matlab调用C++函数
-
环境:Matlab2022a、 Vs2015
-
目前没有用到这一块记录一下为以后提供帮助
-
MATLAB C++ API 只适用于2018a及以后的版本(低版本只有 C 矩阵 API)
-
下面这是一个官方示例可提供学习
#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].getNumberOfElements() != 1)
{
matlabPtr->feval(u"error",0,
std::vector<Array>({factory.createScalar("First input mmust 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") }));
}
}
};
% 选择编译器
mex -setup C++
% 编译
mex MyMEXFunction.cpp
%调用
b = MyMEXFunction(11.5, rand(1000));