c++ - 使用带有 MEX Wrapper 的辅助 C 文件从 MATLAB 2016 调用 C++ 代码时遇到问题

标签 c++ c matlab mex extern

我需要从 MATLAB 2016 调用 C++ 非成员函数。MATLAB 直到 2018 年才支持 C++ MEX,因此这会带来问题。

我在 Windows 中的 mingw64 下执行此操作。

为了解决这个问题,我尝试制作一个带有 MEX 包装器的 C 文件,根据一些在线建议,C 实现纯粹只是使用带有外部“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]);
}

实际实现: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 是投诉)
  • 头文件很可能全错了,并声称“在 std 的声明中类型默认为 int”。我假设这是因为我在 C 部分中有一些与 C++ 相关的内容。我不确定如何处理这个问题。
  • C++ 文件提示最多。我可以发布所有错误,但考虑到我的逻辑中可能存在根本缺陷,我认为这不会产生任何效果。

一个很大的障碍是从 MATLAB -> C -> C++ 传递输入参数的方法。我不希望事情“丢失”,理想情况下,除非必要,否则我不想进行转换,而且我不确定那会在哪里。

最佳答案

  1. 你不能把std::vector<>extern "C"部分,因为它不是有效的 C 语法。您需要创建一个纯 C 函数 stub ,编译为 C++,调用 C++ 函数。

  2. 但是,您不需要执行任何操作,因为您可以很好地编译 C++ MEX 文件。 API 是 C 语言,但您可以毫无问题地从 C++ 调用 C 函数。

  3. 您的实际问题mexFunction是您将指针传递给 mxArray函数期望引用 std::vector<> 的对象等等。正确执行此操作的唯一方法是将数据从 MATLAB 数组复制到 C++ vector 中:

#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]);
}

关于c++ - 使用带有 MEX Wrapper 的辅助 C 文件从 MATLAB 2016 调用 C++ 代码时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56385006/

相关文章:

c++ - 如何检查计算机是否存在?

c++ - C/C++ 中将数组作为形式参数传递为 int arr[] 和 int arr[N] 之间的区别

c++ - 输入 "cobra"输出 "dpcsb"将 1 个字符转换为下一个 C++

c - pthread_join() 不起作用

c - 获取变量的十六进制地址作为 uintptr_t

c++ - MATLAB 运算的 Armadillo 等效项

c++ - 如何中断绑定(bind)到 istream_iterator 的输入流

c - 在 C 中分配内存的所有方法是什么?它们有何不同?

matlab - quiver3 返回长度不正确的向量

MATLAB:将矩阵 reshape 为数组后,我们如何知道值原来属于哪里?