Develop Interface for External C/C++ Code
You can develop an interface to external code by using the base class coder.ExternalDependency
. Using a class for external code can provide certain
advantages. You can:
Place related functions into a single package, without exposing them to the user (encapsulation).
Create an extensible interface that can be shared across projects.
Define custom build configuration settings so that build information is preconfigured.
Create a class from coder.ExternalDependency
To instantiate a class derived from the abstract class
coder.ExternalDependency
, you must define the methods
getDescriptiveName
, isSupportedContext
, and
updateBuildInfo
. These methods address error reporting, build
support, and build configuration.
Consider an example of a subclass called myExternalMathAPI
derived
from coder.ExternalDependency
. This subclass assumes that you have
all your
needed source and header files contained in your
current working folder, with no other
dependencies. If you have additional dependencies, such as source, library, or header
files, you can redefine updateBuildInfo
, or derive a subclass from
myExternalMathAPI
which overloads the
updateBuildInfo
method as
necessary and adds new methods to the interface.
To assist in build configuration, you can use the build information and build context
objects accessible by the updateBuildInfo
method.
classdef myExternalMathAPI < coder.ExternalDependency %#codegen methods (Static) % Provide a name for use in error messages function bName = getDescriptiveName(~) bName = 'myExternalMathAPI'; end % Error out if build context is not supported function supported = isSupportedContext(buildContext) myTarget = {'mex','rtw'}; if buildContext.isCodeGenTarget(myTarget) supported = true; else error('API only supported for mex, lib, exe, dll'); end end % Configure simple build in this example % Redefine the method as necessary for your dependencies function updateBuildInfo(buildInfo, buildContext) src = {'extAdd.c','extSub.c','extDiv.c'}; buildInfo.addSourceFiles(src); end % Define class methods function c = add(a, b) coder.cinclude('extAdd.h'); c = 0; c = coder.ceval('extAdd', a, b); end function c = subtract(a, b) coder.cinclude('extSubtract.h'); c = 0; c = coder.ceval('extSub', a, b); end function c = divide(a, b) coder.cinclude('extDivide.h'); c = 0; c = coder.ceval('extDiv', a, b); end end end
Call the external C/C++ code through the interface:
myExternalMathAPI.add(a,b); myExternalMathAPI.substract(a,b); myExternalMathAPI.divide(a,b);
Best Practices for Using coder.ExternalDependency
Provide an Error Message for Unsupported Build
The isSupportedContext
method returns true if the external
code interface is supported in the build context. If the external code interface is
not supported, use error
to terminate code generation with an
error message. For
example:
function supported = isSupportedContext(buildContext) if buildContext.isMatlabHostTarget() supported = true; else error('MyLibrary is not available for this target'); end end
Parametrize Methods for MATLAB and Generated Code
Parametrize methods that call external functions so that the methods run in MATLAB®. For example:
function c = add(a, b) if coder.target('MATLAB') % running in MATLAB, use built-in addition c = a + b; else % running in generated code, call library function c = 0; c = coder.ceval('extAdd', a, b); end end
Parametrize updateBuildInfo for Multiple Platforms
Parametrize the updateBuildInfo
method to support multiple
platforms. For example, use coder.BuildConfig.getStdLibInfo
to get the platform-specific library
file
extensions.
function updateBuildInfo(buildInfo, buildContext) % Get file extensions for the current platform [~, linkLibExt, execLibExt, ~] = buildContext.getStdLibInfo(); % Parametrize library extension libName = strcat('myLib', linkLibExt); % Other linking parameters libPath = 'c:\Link_Objects'; libPriority = ''; libPreCompiled = true; libLinkOnly = true; % Linking command buildInfo.addLinkObjects(libName,libPath,libPriority,libPreCompiled,libLinkOnly); end
See Also
coder.ExternalDependency
| coder.BuildConfig
| error
| coder.ceval
| coder.updateBuildInfo