Integrate Multiple Generated C++ Code Projects
This example shows how to integrate two different generated C++ code projects into a single, larger project.
Your generated code projects might have similar function names, but have different settings, parameters, or functionality. Generate code with namespaces to aid in integrating different projects that share the same names. Namespaces can also improve code readability.
Generate C++ Code for a MATLAB® Algorithm
Consider a simple MATLAB function that returns a gravitational constant. The value of the gravitational constant is derived from a global variable.
type getGravityConst.m
function c = getGravityConst %#codegen global g c = g;
Suppose that you want to generate code for getGravityConst
that models scenarios for the Moon and for the Earth. Generate two separate code projects with the same entry-point function. Specify a different global value, and hence, gravitational constant, for each project.
Create a code generation configuration object. Specify:
DLL build type.
C++ target language.
The name of the orbital body as the namespace.
#pragma once
style#include
guards.Packaging of the generated code files into a
.zip
file by calling thepackNGo
function.
cfg = coder.config('dll'); cfg.TargetLang = "C++"; cfg.CppNamespace = 'moon'; cfg.HeaderGuardStyle = "UsePragmaOnce"; cfg.PostCodeGenCommand = 'packNGo(buildInfo)';
Generate code for getGravityConst
to model the Moon:
By using the previously defined configuration object.
With a code generation report.
Such that the code returns the Moon's value of the gravitational constant in units of m/s^2.
In an output folder called
projectMoon
.With output binaries called
getGravityConstMoon
.
codegen getGravityConst -config cfg -report -globals {'g', -1.62} ... -d projectMoon -o getGravityConstMoon
Code generation successful: View report
To generate code for getGravityConst
that models the earth, first modify the:
Namespace name
Gravitational constant
Output file name
Output folder name
cfg = coder.config('dll'); cfg.TargetLang = "C++"; cfg.CppNamespace = 'earth'; cfg.HeaderGuardStyle = "UsePragmaOnce"; cfg.PostCodeGenCommand = 'packNGo(buildInfo)'; codegen getGravityConst -config cfg -report -globals {'g', -9.81} ... -d projectEarth -o getGravityConstEarth
Code generation successful: View report
Project Integration Scenario: Planetary Modeling
Suppose that you want to design a larger project that performs planetary modeling and computes quantities such as the flight times of falling objects. The flight time depends on the gravitational constant for each planet and the initial height of the object. You want to use the generated code functions for getGravityConst
in this larger project.
Determine the Platform-Dependent File Extensions
The generated dynamic libraries have different extensions on different platforms. This code determines the correct extensions for your platform.
dllext = ''; libext = ''; if ismac dllext = '.dylib'; libext = dllext; elseif isunix dllext = '.so'; libext = dllext; elseif ispc dllext = '.dll'; libext = '.lib'; else disp('Platform not supported') return end
Write a Main File That Uses the Generated Code Projects
In the general case, you integrate different projects by writing or modifying a main file to call each of the projects' functions. By using namespaces, you can distinguish the generated functions for each project, even though the function names are the same.
For an example of how to write a main file that uses the generated C++ code for both projects, see the attached file main_planetSim.cpp
. To build an executable or binary from the main file, you must specify or provide the following to the build tools (compiler, linker, and/or IDE) and their correct paths:
Header files for any called functions.
On Windows platforms, import libraries (
.lib
files).Dynamic libraries (
.dll
,.so
and.dylib
files).Include directories for other generated source and include files.
The .zip
files that the packNGo
command creates during code generation contain the generated code files. Unpack the zip files to folders in your build directory or build environment. You must also make your dynamic libraries accessible to the executable, for example, by moving the generated dynamic libraries to the same folder as the executable.
Write a MATLAB Function that Integrates the Two Projects
As an alternative to writing a main file by hand, you can also integrate two projects into a third generated code project by using the coder.ceval
function. The coder.ceval
function enables you to call external C/C++ code from generated C/C++ code.
The file planetSim.m
shows how to use coder.ceval
and associated build configuration functions to integrate the generated projects into the larger project.
function [t_m, t_e] = planetSim %#codegen % Example function that integrates generated code projects with namespaces d = 10; g = 0; % Add #include statements for external function names coder.cinclude('../projectMoon/getGravityConst.h'); coder.cinclude('../projectEarth/getGravityConst.h'); % Call external functions & do computations g = coder.ceval('moon::getGravityConst'); t_m = timeToDrop(d,g); g = coder.ceval('earth::getGravityConst'); t_e = timeToDrop(d,g); function t = timeToDrop(d,g) t = sqrt(2*d/(-g));
Generate MEX code for the planetSim
function:
linkObjectMoon = ['projectMoon/getGravityConstMoon' libext]; linkObjectEarth = ['projectEarth/getGravityConstEarth' libext]; cfg = coder.config('mex'); cfg.TargetLang = "C++"; codegen('planetSim','-config',cfg,'-d','planetSim','-report',linkObjectMoon,linkObjectEarth)
Code generation successful: View report
Test the Generated MEX Function
Use the MEX function to test the generated code in the MATLAB environment. The MEX function must have access to the generated link libraries. Move the link libraries to the current directory and call the MEX function.
copyfile(['projectMoon/getGravityConstMoon' dllext]); copyfile(['projectEarth/getGravityConstEarth' dllext]); [t_m, t_e] = planetSim_mex
t_m = 3.5136
t_e = 1.4278
The output shows the flight times for the falling object on the Moon and on the Earth.
See Also
coder.config
| codegen
| coder.cinclude
| coder.ceval
| packNGo
| coder.CodeConfig