Main Content

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

| | | |

Related Topics