Main Content

外部 C/C++ コードのインターフェイスの開発

基底クラス coder.ExternalDependency を使用することで、外部コードに対するインターフェイスを開発できます。外部コード用のクラスを使用することには一定の利点があります。次のことが可能です。

  • ユーザーに公開することなく関連する関数を単一のパッケージに配置する (カプセル化)。

  • 複数のプロジェクトで共有できる拡張可能なインターフェイスを作成する。

  • ビルド情報が事前構成されるように、カスタム ビルド構成設定を定義する。

coder.ExternalDependency からのクラスの作成

抽象クラス coder.ExternalDependency から派生したクラスをインスタンス化するには、メソッド getDescriptiveNameisSupportedContext および updateBuildInfo を定義しなければなりません。これらのメソッドはエラー レポート、ビルド サポートおよびビルド構成に対処します。

coder.ExternalDependency から派生した myExternalMathAPI と呼ばれるサブクラスの例について考えます。このサブクラスは、必要なソースとヘッダー ファイルがすべて現在の作業フォルダーに格納されており、その他の依存関係が存在しないものとみなします。ソース、ライブラリまたはヘッダー ファイルといった追加の依存関係が存在する場合は、updateBuildInfo を再定義するか、必要に応じて updateBuildInfo メソッドをオーバーロードして新しいメソッドをインターフェイスに追加する myExternalMathAPI からサブクラスを派生させることができます。ビルド構成を容易にするために、updateBuildInfo メソッドによってアクセス可能なビルド情報とビルド コンテキスト オブジェクトを使用することができます。

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

インターフェイスを介して外部 C/C++ コードを呼び出します。

myExternalMathAPI.add(a,b);
myExternalMathAPI.substract(a,b);
myExternalMathAPI.divide(a,b);

coder.ExternalDependency 使用のベスト プラクティス

サポートされていないビルドに関するエラー メッセージの提供

外部コード インターフェイスがビルド コンテキストでサポートされている場合、isSupportedContext メソッドは true を返します。外部コード インターフェイスがサポートされていない場合、error を使用してエラー メッセージを表示してコード生成を終了します。たとえば、次のようにします。

function supported = isSupportedContext(buildContext)
    if  buildContext.isMatlabHostTarget()
        supported = true;
    else
        error('MyLibrary is not available for this target');
    end
end

MATLAB および生成コードに対するメソッドのパラメーター化

メソッドが MATLAB® で実行されるように、外部関数を呼び出すメソッドをパラメーター化します。たとえば、次のようにします。

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

複数のプラットフォームに対する updateBuildInfo のパラメーター化

updateBuildInfo メソッドをパラメーター化して、複数のプラットフォームをサポートします。たとえば、coder.BuildConfig.getStdLibInfo を使用して、プラットフォーム固有のライブラリ ファイル拡張子を取得します。

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

参考

| | | |

関連するトピック