How to compile Matlab class into C lib?

后端 未结 2 2054
遥遥无期
遥遥无期 2020-12-19 14:10

The origin of this question is from here How to use "global static" variable in matlab function called in c.

I\'m trying to encapsulate the \"global variab

2条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-19 15:02

    As noted by Alan, I was only suggesting using handle class as a container for your global variables (with the benefit that such an object would be passed by reference). The created object is not intended to be directly manipulated by your C++ code (it will be stored in the generic mxArray/mwArray C/C++ struct).

    As far as I know, you cannot directly compile classdef-style MATLAB classes into proper C++ classes when building shared libraries using the MATLAB Compiler. It only supports building regular functions. You could create functional interfaces to MATLAB class member methods, but that's a different story...

    Perhaps a complete example would help illustrate the idea I had in mind. First lets define the code on the MATLAB side:

    GlobalData.m

    This is the handle class used to store the global vars.

    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 wrapper function that acts as a constructor to the above class

    function globals = create_globals()
        %CREATE_GLOBALS  Instantiate and return global state
    
        globals = GlobalData();
        globals.val = 2;
    end
    

    fcn_add.m, fcn_times.m

    MATLAB functions to be exposed as C++ functions

    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
    

    With the above files stored in current directory, lets build the C++ shared library using the MATLAB Compiler:

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

    You should expect the following generated files among others (I'm on a Windows machine):

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

    Next, we could create a sample C++ program to test the library:

    main.cpp

    // Sample program that calls a C++ shared library created using
    // the MATLAB Compiler.
    
    #include 
    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);
    }
    

    Lets build the standalone program:

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

    And finally run the executable:

    >> 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

提交回复
热议问题