从调用MATLAB中的MEX C ++类的方法(Calling methods of C++ cla

2019-07-20 16:34发布

我有一个DLP试剂盒,其我需要使用C ++ API经由MATLAB来控制。

说,我用C / C ++为函数/方法{load_data, load_settings,display_data}在MEX文件名为dlp_controller.cpp / .C。

我知道我可以调用dlp_controller(); 与MATLAB。

有没有一种方法,我可以直接调用这个MEX的方法从MATLAB?

说我dlp_controller.cpp MEX看起来:

class dlp{ ... }
dlp::dlp{ ... }
dlp::load_data{ ... }
dlp::load_settings{ ... }
dlp::display_data{ ... }

void mexFunction(int nlhs, mxArray *[],int nrhs, const mxArray *prhs[]{ ... }

我能以某种方式调用像方法dlp_controller.load_data从MATLAB? 注:一种解决方法可以发送变量dlp_controller并调用内部使用功能和传递的数据。

Answer 1:

据我所知,有这样做没有简单的方法,因为mexFunction接口是相当平坦 。 不过,也有一些不同的解决方法,我能想到的,应该让你接近。 选择根据您的需要最好的之一。

  1. 最简单的是创建一个全局实例dlp在MEX功能类。 使MEX函数的第一个参数调用指示其全局对象的成员函数被调用的字符串。 最明显的缺点是,你已经把你的MEX函数到一个单例。

  2. 如果你需要一个以上的dlp例如,您可以创建在MEX功能,一些全球集装箱std::map<std::string, dlp>例如,然后是指每个dlp一些名字从内部MATLAB实例。 例如,创建一个新的实例,你会调用MEX函数与不已经在存在一个名称map 。 然后,你可以调用MEX函数与此名称,一个字符串,指示调用哪个成员函数,任何参数传递给成员函数。 还设置了一些约定,通过它可以删除一个dlp从实例map

  3. 第二个解决方案类似,而不是命名dlp情况下,你可以返回的句柄到每个实例。 例如,创建一个全球性std::set<dlp *>当你有MEX函数创建一个新的dlp实例,将其添加到set ,并在该指针的拷贝到所分配的对象返回到MATLAB(坚持下去类型的标量变量mxUINT64_CLASS )。 后续调用来调用成员函数对象将这个句柄变量传递给从MATLAB的MEX功能,你会适当的MEX文件中投它时,发现它的内在set并调用成员函数。

这些方法都不是特别漂亮,但这些是唯一的方法,我知道的调用C ++类的成员函数从MEX文件中。



Answer 2:

你可能想看看这份提交给MATLAB中心。 据我所知,它演示的最佳实践,与新闻组的建议许多包括MathWorkers发展。

http://www.mathworks.co.uk/matlabcentral/fileexchange/38964-example-matlab-class-wrapper-for-a-c++-class



Answer 3:

最简单的是设计一个MEX包装,保持类对象的实例,并派遣到MEX二进制的呼叫。 我已经做了图书馆对那些试图开发C ++中的MEX包装。

https://github.com/kyamagu/mexplus

这里是一个快速片段。

// C++ class to be wrapped.
class Database;
// Instance session storage.
template class mexplus::Session<Database>;
// Constructor.
MEX_DEFINE(new) (int nlhs, mxArray* plhs[],
                 int nrhs, const mxArray* prhs[]) {
  InputArguments input(nrhs, prhs, 1);
  OutputArguments output(nlhs, plhs, 1);
  output.set(0, Session<Database>::create(
      new Database(input.get<std::string>(0))));
}
// Destructor.
MEX_DEFINE(delete) (int nlhs, mxArray* plhs[],
                    int nrhs, const mxArray* prhs[]) {
  InputArguments input(nrhs, prhs, 1);
  OutputArguments output(nlhs, plhs, 0);
  Session<Database>::destroy(input.get(0));
}
// Member method.
MEX_DEFINE(query) (int nlhs, mxArray* plhs[],
                   int nrhs, const mxArray* prhs[]) {
  InputArguments input(nrhs, prhs, 2);
  OutputArguments output(nlhs, plhs, 1);
  const Database& database = Session<Database>::getConst(input.get(0));
  output.set(0, database.query(input.get<string>(1)));
}
// And so on...
MEX_DISPATCH


Answer 4:

对于它的价值,这是我拿的问题。 请参阅在例如MEX文件和类包装这GitHub库 。 这是我想出了一小会儿前一个解决方案,我刚才发现了这个问题,而各具特色的回答一个相关的问题 。 希望这会有所帮助的人。

设计目标

  • 管理一个C的多个持久实例++类
  • 连续小整数手柄在使用MATLAB(不投三分球)
  • 透明地处理资源管理(即MATLAB从来不是分配给C ++类的内存负责):
    1. 没有内存泄漏,如果MATLAB未能发出“删除”操作。
    2. 自动释放,如果MEX文件过早地卸载。
  • 防止过早卸载模块卫队
  • 手柄的有效性,不检查一个神奇的数字隐含验证
  • 没有包装类或模仿mexFunction功能,只是在mexFunction一个直观的switch-case块。

需要注意的是,这些目标应该不考虑任何MATLAB类中acheved,但也可以有助于解决内存管理问题。 这样,所得到的MEX文件可以安全地直接使用(但不是太优雅)。

实施概述

对于你的C ++类, class_typemexFunction使用静态数据存储空间来保存持久(调用之间mexFunction整数手柄和智能指针)表来动态分配的类实例。 一个std::map被用于此目的,这有利于查找已知的把手,为此类的唯一有效的情况下,保证存在:

typedef unsigned int handle_type;
std::map<handle_type, std::shared_ptr<class_type>>

std::shared_ptr当或者(1)的表元素通过“删除”动作,或者(2)MEX-文件被卸载擦除照顾解除分配的。

为了防止MEX文件,从而MATLAB类的实例存在卸载, mexLock被称为每次创建一个新的C ++类实例的时间,增加了MEX文件的锁计数。 每一个C ++实例被删除时mexUnlock被调用时,除去锁计数一个锁。

使用

  1. [在的.cpp]枚举不同的动作在动作枚举(例如新建,删除,插入等)。 对于每一个枚举动作,指定一个字符串(如“新”,“删除”,“插入”等)作为第一个参数,以MATLAB中的MEX函数传递。
  2. [在的.cpp]自定义处理用于在体内的switch语句的每个动作mexFunction (例如调用相关的C ++类的方法)。
  3. [在.M](可选)创建,从派生的类cppclass ,创造你的类所需的操作简单的方法。

要求

现代编译器下面的C ++ 11周的特点:

  • shared_ptr
  • auto
  • enum class
  • initializer_list (为const map初始化)

的Visual Studio 2013,最近的GCC(可能具有-std=c++11 ),并自锵3.1。

资源

  • C ++组分(class_wrapper_template.cpp) ( mexFunction和实例地图)。 重命名和编辑此为++,你要管理的温度。
  • 基类(cppclass.m)用于通过MEX文件管理的单个实例


Answer 5:

另类设计,清洁的使用情况在这里,是定义一个单独的类以init,fcnA,fcnB,fcnC,... ...方法等,与相应的轻型包装..然后调用来自墨西哥的包装。

class A {
  public:
     A getInstance() {
        if ( !instance )
             instance = new A(...);
        return instance;
     }

    void fcnA(T1 a1, T2 a2) {
           //yada yada
     }

  private:
    static A* instance;
};
A::instance = NULL;

//begin wrappers for marshalling to class method
A* getInstance( ) {
   return A::getInstance();
}

void fcnA(T1 a1, T2 a2) {
   getInstance()->fcnA(a1,a2);
}

//ad nauseum


文章来源: Calling methods of C++ class in MEX from MATLAB