无法使用辅助 C 文件从 MATLAB 2016 调用 C++ 代码 w/MEX Wrapper
Trouble calling C++ code from MATLAB 2016 using a helper C file w/MEX Wrapper
我需要从 MATLAB 2016 调用 C++ 非成员函数。MATLAB 直到 2018 年才支持 C++ MEX,所以这会带来问题。
我在 mingw64 下的 Windows 中这样做。
为了解决这个问题,我尝试制作一个带有 MEX 包装器的 C 文件,C 实现纯粹只是根据一些在线建议使用带有 extern "C" 的共享头文件调用 C++ 函数。
不过,我是 MATLAB 的新手,在这里从 C 调用 C++ 和其他一些概念。所以没有任何东西可以正确编译。
非常感谢任何有关正确处理此问题的建议。
头文件myFunc.h:
#ifndef CPP_H
#define CPP_H
#ifdef __cplusplus
void myFunc(const std::vector<myStruct>& a,
const std::vector<myStruct>& b,
const double c,
std::vector<std::pair>& d,
mxArray **e
);
extern "C" {
#endif
void myFunc(const std::vector<myStruct>& a,
const std::vector<myStruct>& b,
const double c,
std::vector<std::pair>& d,
mxArray **e
);
#ifdef __cplusplus
}
#endif
#endif
调用它的C文件,myFuncCaller.c:
#include "myFunc.h"
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
myFunc(prhs[0], prhs[1], prhs[2], prhs[3], prhs[4]);
}
实际implementation:myFunc.cpp:
#include "myFunc.h"
void myFunc(const std::vector<myStruct>& a,
const std::vector<myStruct>& b,
const double c,
std::vector<std::pair>& d,
mxArray **e
)
{
//things done here, pushes results to d
}
尝试编译这两个的最终结果是:
- C 文件没有看到 mex.h(不确定为什么,因为 MATLAB 声称 mingw 是投诉)
- 头文件可能全错了,并声称 "type defaults to int in declaration of std"。我假设这是因为我在 C 部分中有一些与 C++ 相关的内容。我不确定如何处理这个问题。
- C++ 文件抱怨最多。我可以 post 所有错误,但考虑到我的逻辑中可能存在根本性缺陷,我认为这不会有成效。
一个很大的障碍是从 MATLAB -> C -> C++ 传递输入参数的方法。我不希望事情变成 "lost" 并且理想情况下不想进行转换,除非有必要,而且我不确定那会在哪里。
您不能将 std::vector<>
放在 extern "C"
部分中,因为它不是有效的 C 语法。您需要创建一个纯 C 函数存根,编译为 C++,调用 C++ 函数。
但是,您不需要执行任何操作,因为您可以编译 C++ MEX-file 就好了。 API 是 C 语言,但您可以毫无问题地从 C++ 调用 C 函数。
你的 mexFunction
中的实际问题是你将指针传递给 mxArray
函数期望引用 std::vector<>
等的对象。唯一的方法是这个权利是将MATLAB数组中的数据复制到C++向量中:
#include "myFunc.h"
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
if (nrhs < 5) {
mexErrMsgTxt("Not enough input arguments! 5 expected.");
}
// arg 1: std::vector<myStruct>
if (!mxIsDouble(prhs[0])) {
mexErrMsgTxt("First input argument must be a double array.");
}
std::size_t N = mxGetNumberOfElements(prhs[0]);
double* pr = mxGetPr(prhs[0]);
std::vector<myStruct> a(N);
std::copy(pr, pr+N, a.begin());
// arg 2: std::vector<myStruct>
std::vector<myStruct> b;
// ...
// arg 3: double
double c = mxGetScalar(prhs[2]);
// arg 4: std::vector<std::pair> // This makes no sense in C++, std::pair<> is a template, 2 template arguments missing!!
std::vector<std::pair> d;
// ...
// arg 5: mxArray ** // is this the output? Why does your C++ function take an mxArray?
myFunc(a, b, c, d, &prhs[4]);
}
我需要从 MATLAB 2016 调用 C++ 非成员函数。MATLAB 直到 2018 年才支持 C++ MEX,所以这会带来问题。
我在 mingw64 下的 Windows 中这样做。
为了解决这个问题,我尝试制作一个带有 MEX 包装器的 C 文件,C 实现纯粹只是根据一些在线建议使用带有 extern "C" 的共享头文件调用 C++ 函数。
不过,我是 MATLAB 的新手,在这里从 C 调用 C++ 和其他一些概念。所以没有任何东西可以正确编译。
非常感谢任何有关正确处理此问题的建议。
头文件myFunc.h:
#ifndef CPP_H
#define CPP_H
#ifdef __cplusplus
void myFunc(const std::vector<myStruct>& a,
const std::vector<myStruct>& b,
const double c,
std::vector<std::pair>& d,
mxArray **e
);
extern "C" {
#endif
void myFunc(const std::vector<myStruct>& a,
const std::vector<myStruct>& b,
const double c,
std::vector<std::pair>& d,
mxArray **e
);
#ifdef __cplusplus
}
#endif
#endif
调用它的C文件,myFuncCaller.c:
#include "myFunc.h"
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
myFunc(prhs[0], prhs[1], prhs[2], prhs[3], prhs[4]);
}
实际implementation:myFunc.cpp:
#include "myFunc.h"
void myFunc(const std::vector<myStruct>& a,
const std::vector<myStruct>& b,
const double c,
std::vector<std::pair>& d,
mxArray **e
)
{
//things done here, pushes results to d
}
尝试编译这两个的最终结果是:
- C 文件没有看到 mex.h(不确定为什么,因为 MATLAB 声称 mingw 是投诉)
- 头文件可能全错了,并声称 "type defaults to int in declaration of std"。我假设这是因为我在 C 部分中有一些与 C++ 相关的内容。我不确定如何处理这个问题。
- C++ 文件抱怨最多。我可以 post 所有错误,但考虑到我的逻辑中可能存在根本性缺陷,我认为这不会有成效。
一个很大的障碍是从 MATLAB -> C -> C++ 传递输入参数的方法。我不希望事情变成 "lost" 并且理想情况下不想进行转换,除非有必要,而且我不确定那会在哪里。
您不能将
std::vector<>
放在extern "C"
部分中,因为它不是有效的 C 语法。您需要创建一个纯 C 函数存根,编译为 C++,调用 C++ 函数。但是,您不需要执行任何操作,因为您可以编译 C++ MEX-file 就好了。 API 是 C 语言,但您可以毫无问题地从 C++ 调用 C 函数。
你的
mexFunction
中的实际问题是你将指针传递给mxArray
函数期望引用std::vector<>
等的对象。唯一的方法是这个权利是将MATLAB数组中的数据复制到C++向量中:
#include "myFunc.h"
#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
if (nrhs < 5) {
mexErrMsgTxt("Not enough input arguments! 5 expected.");
}
// arg 1: std::vector<myStruct>
if (!mxIsDouble(prhs[0])) {
mexErrMsgTxt("First input argument must be a double array.");
}
std::size_t N = mxGetNumberOfElements(prhs[0]);
double* pr = mxGetPr(prhs[0]);
std::vector<myStruct> a(N);
std::copy(pr, pr+N, a.begin());
// arg 2: std::vector<myStruct>
std::vector<myStruct> b;
// ...
// arg 3: double
double c = mxGetScalar(prhs[2]);
// arg 4: std::vector<std::pair> // This makes no sense in C++, std::pair<> is a template, 2 template arguments missing!!
std::vector<std::pair> d;
// ...
// arg 5: mxArray ** // is this the output? Why does your C++ function take an mxArray?
myFunc(a, b, c, d, &prhs[4]);
}