I am trying to test some code that has been generated from Matlab into C++.
To do this I am attempting to integrate and run the generated C++ code back into Matlab.
Here's the function I am trying to use (in Matlab pre-autogen)
function out = getRotationMatrix(aStruct)
out = aStruct.bank_rad*aStruct.heading_rad+aStruct.pitch_rad;
end
I autogenerate it using this ...
function varargout = AutoGenCode(varargin)
% Here we are attempting to generate a C++ class from a matlab function via a
% hosting function
% initialise
varargout = {};
% create instance of config object
cfg = coder.config('LIB');
% config options
cfg.MaxIdLength = int32(64);
cfg.TargetLang = 'C++';
cfg.CppPreserveClasses = 1;
cfg.EnableCustomReplacementTypes = true;
cfg.ReplacementTypes.uint32 = 'uint32_t';
cfg.CppInterfaceStyle = 'Methods';
cfg.CppInterfaceClassName = 'FrameTransformation';
cfg.FilePartitionMethod = 'MapMFileToCFile'; % or 'MapMFileToCFile' SingleFile
cfg.EnableVariableSizing = false;
%cfg.PreserveVariableNames = 'UserNames'; % Worse
%cfg.IncludeInitializeFcn = true;
cfg.PassStructByReference = true;
thisStruct.bank_rad = 2.1;
thisStruct.heading_rad = 3.1;
thisStruct.pitch_rad = 3.1;
codegen -config cfg getRotationMatrix -args {thisStruct} -report -preservearraydims -std:c++11
end
To move to another area (\unzipped) I use packNGo
load([pwd,'\codegen\lib\getRotationMatrix\buildInfo.mat'])
packNGo(buildInfo,'packType', 'hierarchical','fileName','portzingbit')
Now when i try to re-integrate it i am using clib
cd 'D:\thoros\Components\Frame Transformation Service\FT_V2\unzippedCode'
clibgen.generateLibraryDefinition('FrameTransformation.h','Libraries',{'getRotationMatrix.lib'})
build(defineFrameTransformation)
addpath('D:\thoros\Components\Frame Transformation Service\FT_V2\unzippedCode\FrameTransformation')
Where I had to define the < SHAPE > parameter in the defineFrameTransformation.mlx manually to be 1
When i try and use the function I cant pass a structure without an error
A = clib.FrameTransformation.FrameTransformation()
thisStruct.bank_rad = 2.1;
thisStruct.heading_rad = 3.1;
thisStruct.pitch_rad = 3.1;
>> A.getRotationMatrix(thisStruct)
I get the following error
Unrecognized method, property, or field 'getRotationMatrix' for class 'clib.FrameTransformation.FrameTransformation'.
The problem disappears if rewrite and regenerate the function to accept non-structure input e.g. double.
By using the summary function i can see that the call to getRotationMatrix should be of type clib.FrameTransformation.struct0_T
However i can't seem to create a variable of this type.
summary(defineFrameTransformation)
MATLAB Interface to FrameTransformation Library
Class clib.FrameTransformation.struct0_T
No Constructors defined
No Methods defined
No Properties defined
Class clib.FrameTransformation.FrameTransformation
Constructors:
clib.FrameTransformation.FrameTransformation()
clib.FrameTransformation.FrameTransformation(clib.FrameTransformation.FrameTransformation)
Methods:
double getRotationMatrix(clib.FrameTransformation.struct0_T)
No Properties defined
So how is one supposed to pass structures to C++ libraries in Matlab ??? what am i doing wrong.
Note Matlab 2020B, windows, Visual studio 2019
Ah, you were so close to the solution :)
There was a small catch there.
When you are using clibgen.generateLibraryDefinition()
you have to make sure that all the type definition are included in the header file. In your case the definition of struct0_T
was presnet inside getRotationMatrix_types.h
file.
So you will have to include both the headers using below command :
clibgen.generateLibraryDefinition(["FrameTransformation.h","getRotationMatrix_types.h"],"PackageName","mylib",'Libraries',{'getRotationMatrix.lib'})
Now you will have to fill the additional details required in the definition file.
Once you finish that step, you can use below commands to successfully use the interface
build(definemylib)
addpath('\\mathworks\home\dramakan\MLAnswers\CLIB_With_Codegen\ToPort\portzingbit\mylib')
A = clib.mylib.FrameTransformation
s = clib.mylib.struct0_T
s.bank_rad =2.1;
s.heading_rad =3.1;
s.pitch_rad=3.1;
A.getRotationMatrix(s)
I could get below output in R2021b
>> A.getRotationMatrix(s)
ans =
9.6100
Additionally check if you can use MATLAB Coder MEX instead of doing all these circus. You can call the generated code directly in MATLAB using MEX. You can refer below documentation : https://www.mathworks.com/help/coder/gs/generating-mex-functions-from-matlab-code-at-the-command-line.html