-->

如何编译Matlab的类为C的lib?(How to compile Matlab class in

2019-08-18 16:16发布

这个问题的起源是从这里如何叫在C matlab函数使用“全局静态”变量 。

我试图在“全局变量”封装成一个对象。 但是我不知道如何将MATLAB类导出到C ++使用MATLAB编译器(MCC)

要做到这一点,我刚试过的标准命令

MATLAB命令

mcc -W cpplib:Vowel4 -T link:lib Vowel4.m

MATLAB脚本

classdef Vowel4

  properties
    x
    y
  end

  methods
    Vowel4
    A
    B
  end

end

生成的LIB实际上是独立的功能,而不是C ++类。

我怎么编译的类在Matlab到C ++类?

我一直在寻找一个答案,但一个也没找到。

显然MATLAB命令不适合此方案。 但是我无法找到建设Matlab的类为C ++类的任何信息。

==========================编辑======================= =

实际的cpp的代码如下:@Alan

mclInitializeApplication(NULL, 0);
loadDataInitialize();
soundByCoefInitialize();
loadData(); 

mwArray F(4, 1, mxDOUBLE_CLASS);
float test[4];

for ( ;; ){
    const Frame frame = controller.frame();
    const FingerList fingers = frame.fingers();
    if ( !fingers.empty() ){
        for ( int i = 0; i < 4; i ++ ){
            double v = fingers.count() > i ? (fingers[i].tipPosition().y / 50) - 2 : 0;
            F(i+1,1) = v;
            test[i] = v;
            cout << v << ' ';
        }
        cout << endl;
        soundByCoef(F);
    }
}

在这里,matlabA()对应于loadData(),它加载数据,并soundByCoef(F)对应于matlabB(),它做在主回路的工作。

Answer 1:

正如艾伦指出, 我只使用手柄类作为您的全局变量的容器(有,这样的对象将通过引用传递的好处)提示。 所创建的对象并不旨在由C ++代码进行直接操作(它会被存储在通用mxArray/mwArray C / C ++结构)。

据如我所知 ,你不能直接建立使用MATLAB编译共享库时编译classdef风格MATLAB类为适当的C ++类。 它仅支持建设规律的功能。 您可以创建功能接口,以MATLAB类的成员方法,但是这是一个不同的故事...

也许一个完整的例子将有助于说明想法,我的想法。 首先让定义在MATLAB端的代码:

GlobalData.m

这是用来存储全局变量手柄类。

classdef GlobalData < handle
    %GLOBALDATA  Handle class to encapsulate all global state data.
    %
    % Note that we are not taking advantage of any object-oriented programming
    % concept in this code. This class acts only as a container for publicly
    % accessible properties for the otherwise global variables.
    %
    % To manipulate these globals from C++, you should create the class API
    % as normal MATLAB functions to be compiled and exposed as regular C
    % functions by the shared library.
    % For example: create(), get(), set(), ...
    %
    % The reason we use a handle-class instead of regular variables/structs
    % is that handle-class objects get passed by reference.
    %

    properties
        val
    end
end

create_globals.m

充当一个构造于上述A类包装函数

function globals = create_globals()
    %CREATE_GLOBALS  Instantiate and return global state

    globals = GlobalData();
    globals.val = 2;
end

fcn_add.m,fcn_times.m

MATLAB函数被暴露为C ++函数

function out = fcn_add(globals, in)
    % receives array, and return "input+val" (where val is global)

    out = in + globals.val;
end

function out = fcn_times(globals, in)
    % receives array, and return "input*val" (where val is global)

    out = in .* globals.val;
end

与存储在当前目录中的上述文件,让构建C ++使用MATLAB编译共享库:

>> mkdir out
>> mcc -W cpplib:libfoo -T link:lib -N -v -d ./out create_globals.m fcn_add.m fcn_times.m

您应该会等等(我是一个Windows机器上)下面生成的文件:

./out/libfoo.h
./out/libfoo.dll
./out/libfoo.lib

接下来,我们可以创建一个C ++程序来测试库:

main.cpp中

// Sample program that calls a C++ shared library created using
// the MATLAB Compiler.

#include <iostream>
using namespace std;

// include library header generated by MATLAB Compiler
#include "libfoo.h"

int run_main(int argc, char **argv)
{
    // initialize MCR
    if (!mclInitializeApplication(NULL,0)) {
        cerr << "Failed to init MCR" << endl;
        return -1;
    }

    // initialize our library
    if( !libfooInitialize() ) {
        cerr << "Failed to init library" << endl;
        return -1;
    }

    try {
        // create global variables
        mwArray globals;
        create_globals(1, globals);

        // create input array
        double data[] = {1,2,3,4,5,6,7,8,9};
        mwArray in(3, 3, mxDOUBLE_CLASS, mxREAL);
        in.SetData(data, 9);

        // create output array, and call library functions
        mwArray out;
        fcn_add(1, out, globals, in);
        cout << "Added matrix:\n" << out << endl;
        fcn_times(1, out, globals, in);
        cout << "Multiplied matrix:\n" << out << endl;
    } catch (const mwException& e) {
        cerr << e.what() << endl;
        return -1;
    } catch (...) {
        cerr << "Unexpected error thrown" << endl;
        return -1;
    }

    // destruct our library
    libfooTerminate();

    // shutdown MCR
    mclTerminateApplication();

    return 0;
}

int main()
{
    mclmcrInitialize();
    return mclRunMain((mclMainFcnType)run_main, 0, NULL);
}

让我们建立独立的程序:

>> mbuild -I./out main.cpp ./out/libfoo.lib -outdir ./out

最后运行可执行文件:

>> cd out
>> !main
Added matrix: 
     3     6     9 
     4     7    10 
     5     8    11 
Multiplied matrix: 
     2     8    14 
     4    10    16 
     6    12    18 

HTH



Answer 2:

从线程继以前的帖子 ,有人建议不要换你的功能类,而是使用一个类来传递对全局变量编译让你无法使用。

classdef Foo < handle
  properties
    value
  end

  methods
    function obj = Foo(value)
      obj.value = value;
    end
  end
end

注意:类Foo扩展handle ,以使其按引用传递,而不是按值传递类。 请参阅: 手柄和价值类之间的比较 。

function foo = matlabA()
  foo = new Foo(1);
end

function matlabB(foo)
  foo.value
end

据我所知,MATLAB编译器不编译代码本身,而是与MATLAB组件运行时的副本,其打包并写了一些包装函数来处理从C / C ++中的代码调用运行时说。

我会建议避免来回跳跃MATLAB和C / C ++太多之间; 必然有一些开销来转换数据类型和调用MCR。 我真正使用它是结束了一个复杂而自足的MATLAB脚本(即:不需要用C / C ++代码中旬通过该脚本的方式进行交互)作为函数,或包装起来的代码部署到环境不具有MATLAB的完整副本。

作为一个有趣的边注:如果要调用从内Matlab的C ++,和C ++代码需要一个全局变量的访问,事情就容易多了。 你可以简单地通过包装你的C ++代码为做到这一点mexFunction并在编译。 在你需要访问一个变量,它是在Matlab工作空间的地方,你可以这样做使用mexGetVariablePtr将只读指针返回数据。 您正在访问的变量可以在全局工作空间,或者该叫你mexFunction功能。

通过这种方法,我建议慷慨评论说,你在两个C ++和Matlab代码获取变量,它们之间的链接可能从MATLAB侧明显; 你不希望以后有人一起走,编辑脚本,不知道为什么它打破了。

在这种情况下,它似乎是C ++方面并不真正需要访问的数据 ,所以你可以重构它有MATLAB通过包装“获得的手指当前位置”的代码放到一个mexFunction做主叫,然后让MATLAB做环:

data = loadData();
while(~stop) {
  position = getFingerPositionMex();
  soundByCoef(position, data);
}

假设你没有修改中的数据soundByCoef Matlab的将通过参考使用通行证,所以不会有大的数据集的复制。



文章来源: How to compile Matlab class into C lib?