MATLAB Answers

How can I use C++ classes in my MATLAB functions and generate code using MATLAB Coder?

74 views (last 30 days)
I need to use class methods from an external C++ library in my MATLAB function as part of my workflow. How can I use C++ classes in my MATLAB functions and generate code using MATLAB Coder?

Accepted Answer

MathWorks Support Team
MathWorks Support Team on 12 Nov 2015
It is possible to use C++ objects and methods inside the MATLAB code and generate code using the MATLAB Coder. The basic idea is to write a set of C++ functions that act as wrappers for the class methods and call these wrapper functions from within MATLAB Coder.
 
This workflow can be divided into 3 sections:
Part 1 - C++ Source Files:
  • Define a void pointer that will be cast to the object type that will be used in a MATLAB function. This void pointer will be cast to the object type in each wrapper function.
  • Create wrapper functions for class constructors and destructors. The argument to the constructor and destructor wrapper functions will be a void pointer that will be cast into the object type inside the wrapper functions. 
  • Inside the constructor wrapper function, allocate memory on the heap.
  • Inside the destructor wrapper function, use "delete" function to free memory.
  • For each class method that will be used in a MATLAB function, create a wrapper function. One of the arguments for these wrapper functions will be a void pointer.
  • Inside the method wrapper functions, cast void pointer to the object type.
  • Invoke the class methods inside the wrapper functions using the arrow operator (e.g. -> operator).
Part 2 - C++ Header Files:
  • Create a header file for the wrapper functions and encapsulate the header file body with the "extern 'C' " statement in the following way:                                                                                         
#if defined __cplusplus
extern "C" {
#endif
//wrapper header body goes here.
#if defined __cplusplus
}
#endif
This is crucial so that the code can be compiled using a C++ Compiler and name mangling does not occur.
Part 3 - MATLAB Files:
  • Use "coder.opaque" to declare the void pointer type in MATLAB functions. Note that MATLAB code cannot set or access a variable declared using "coder.opaque", but external C/C++ functions can accept it as an argument. Moreover, a variable declared using "coder.opaque" cannot be the output of an entry point MATLAB function.
  • Use "coder.eval" to call the wrapper functions defined in Part 1 from withing MATLAB code. 
The above workflow is mandatory to be able to call methods of a C++ class in MATLAB code. In C++, a class method is invoked using the dot operator.  For example, to invoke the method "mymethod" of the class "myclass", you would use the following command:
myclass.mymethod();
"myclass.mymethod" is not a valid argument for "coder.ceval" in R2015b and earlier releases. Thus, the workaround is to write wrapper functions as explained in the above workflow. Please refer to the MATLAB Coder documentation and release notes for changes in future releases.
Please look at the attached zip file for a simple example of this workflow for a C++ "person" class. The source file is "person.cpp", and the header file is "person.h". The source file for the wrapper functions is "personwrapper.cpp" and the header file is "personwrapper.h". The MATLAB function that uses the wrapper functions is "persontest.m". The MAT-file "configmexexe" loads 2 Configuration objects to the base workspace; one is used for MEX file generation, and the other one is used for standalone executable generation. The "main.cpp" file is used for the executable. Please refer to the MATLAB script "generatecode.m" for generating a MEX file and an executable.

  1 Comment

VenkataPhanindra Challa
VenkataPhanindra Challa on 7 Oct 2019
Hello Team,
I am using MATLAB 2018b version and I need to call external c++ APIs in MATLAB simulink. I would like to know whether still I have to follow the above method or is there any easier methods in newer versions.

Sign in to comment.

More Answers (2)

Geoff McVittie
Geoff McVittie on 10 Jun 2019
Solution to interacting with C++ classes and methods using the standard library
The std::mem_fn, available in functional library of C++11 and forward, automatically wraps member methods of a class. This allows the C++ objects to be declared using coder.opque and instantiated using coder.ceval. The methods can then be called as functions, wrapped by std::mem_fn, directly on the C++ object using coder.ceval in the MATLAB code.
For example, given the C++ class header:
// myclass.h
#ifndef MYCLASS_H
#define MYCLASS_H
#include <iostream>
#include <string>
class MyClass
{
public:
MyClass(void){};
int mymethod(int a)
{
std::cout << "MyClass::mymethod() called with input (" + std::to_string(a) + ")." << std::endl;
return 42;
};
};
#endif
A MATLAB function can then use the class as follows:
function ret = mycode
%MYMCODE Summary of this function goes here
% Detailed explanation goes here
coder.cinclude('<functional>');
coder.cinclude('myclass.h');
p = coder.opaque('MyClass','NULL','HeaderFile','myclass.h');
p = coder.ceval('MyClass');
a = int32(5);
ret = coder.nullcopy(int32(0));
ret = coder.ceval('std::mem_fn(&MyClass::mymethod)',p,a);
end
With regards to memory management, using C++14, the example can be extended using smart ptrs, such as std::unique_ptr, to the following:
function ret = mystrongmcode
%MYMCODE Summary of this function goes here
% Detailed explanation goes here
coder.cinclude('<memory>');
coder.cinclude('<functional>');
coder.cinclude('myclass.h');
p = coder.opaque('std::unique_ptr<MyClass>','NULL','HeaderFile','myclass.h');
p = coder.ceval('std::make_unique<MyClass>');
ret = coder.nullcopy(int32(0));
ret = coder.ceval('std::mem_fn(&MyClass::mymethod)',p);
end
Finally, with regards to overhead, the std::mem_fn does not appear to introduce any overhead. You can confirm this using any online compiler (e.g. https://godbolt.org/).

  9 Comments

Show 6 older comments
VenkataPhanindra Challa
VenkataPhanindra Challa on 28 Oct 2019
Hello,
Thanks for your support !
I am using external cpp header files to call the classes in matlab simulink. When I am trying to code generate with your method it is searching for the other header files which are mentioned in that header file as #include. But I don't want them for my code generation. Is there any possiblity to ignore the other headers and generate the code ?
Thanks in advance !
Geoff McVittie
Geoff McVittie on 28 Oct 2019
Hello,
Again, I would recommend contacting MathWorks Technical support, https://www.mathworks.com/support/contact_us.html as they can give more directed guidance. Interaction with the Simulink Code generation system is beyond the scope of my original post.
Thank you.
VenkataPhanindra Challa
VenkataPhanindra Challa on 7 Nov 2019
Hello,
I would like to know how can I call the below method (str) using coder.ceval ?
namespace abc {
class CS {
public:
et();
virtual ~et();
virtual void srt(std::vector<std::string>);
};
}

Sign in to comment.


Andreas Vollmayr
Andreas Vollmayr on 13 Feb 2017
I don't get the relevance of the example.
As far as I can see, memory management must be done by hand by the matlab user. The C++ object memory is hold by the wrapper. But, there seems to be no exception handling / memory safety at all. All it does is pass pointers to elementary data types.
Could Mathworks please provide a memory safe wrapper example for a stl container. Thank you.

  0 Comments

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!