Main Content

最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。

コード生成のための MATLAB クラスの定義

MATLAB® クラスの効率の良いスタンドアロン コードを生成するには、MATLAB 環境でコードを実行する場合とは異なる方法でクラスを使用しなければなりません。

相違点詳細
制限された一部の言語機能言語制約
制限された一部のコード生成機能クラスと整合性がないコード生成機能
クラス プロパティの定義コード生成のためのクラス プロパティの定義
ハンドル クラスの使用

MATLAB のハンドル クラスおよび System object のコード生成

ハンドル クラス デストラクターのコード生成

コード生成におけるハンドル オブジェクトの制限事項

基底クラス コンストラクターの呼び出し基本クラス コンストラクターの呼び出し
MATLAB ハンドル オブジェクトを含むグローバル変数はコード生成に対応していません。N/A
組み込みの MATLAB クラスからの継承はサポートされていません。サポートされない組み込みの MATLAB クラスからの継承

言語制約

プロパティやメソッドなどの一般的なクラスの機能に対してはコード生成がサポートされていますが、以下のようなサポートされていない高度な機能が数多くあります。

  • イベント

  • リスナー

  • オブジェクトの配列

  • 再帰データ構造体

    • リンク付きリスト

    • Trees

    • グラフ

  • コンストラクターにおける入れ子関数

  • オーバーロードが可能な演算子 subsrefsubsassignsubsindex

    MATLAB では、クラスで独自のバージョンの subsrefsubsassignsubsindex メソッドを定義できます。コード生成では、これらのメソッドの独自の定義をもつクラスはサポートされていません。

  • empty メソッド

    MATLAB のクラスには、クラスの空配列を作成する組み込み静的メソッド empty が含まれています。コード生成は、このメソッドをサポートしていません。

  • 以下の MATLAB ハンドル クラス メソッド:

    • addlistener

    • eq

    • findobj

    • findpro

  • AbortSet プロパティ属性

クラスと整合性がないコード生成機能

  • クラスを使用するエントリポイント MATLAB 関数のコードは生成できますが、MATLAB クラスのコードを直接生成することはできません。

    たとえば、ClassNameA がクラス定義である場合、以下を実行してコードを生成することはできません。

    codegen ClassNameA

  • ハンドル クラス オブジェクトは、エントリポイント関数の入力または出力にできません。

  • 値クラス オブジェクトはエントリポイント関数の入力または出力にすることができます。ただし、値クラス オブジェクトにハンドル クラス オブジェクトが含まれる場合、値クラス オブジェクトはエントリポイント関数の入力または出力にできません。ハンドル クラス オブジェクトは、エントリポイント関数の入力または出力にできません。

  • コード生成は、ハンドル クラスのグローバル変数をサポートしません。

  • コード生成は、値クラスのオブジェクトを調整不可能なプロパティに割り当てることをサポートしていません。たとえば、prop が調整不可能なプロパティであり、かつ v が値クラスに基づいたオブジェクトである場合、obj.prop=v; は無効です。

  • coder.extrinsic を使用してクラスまたはメソッドを外部のものとして宣言することはできません。

  • MATLAB クラスを関数 coder.ceval に渡すことはできません。クラスのプロパティを coder.ceval に渡すことはできます。

  • プロパティに get メソッド、set メソッド、または検証関数がある場合、またはプロパティが特定の属性をもつ System object™ プロパティである場合、そのプロパティを外部関数に参照で渡すことはできません。一部のプロパティでサポートされない参照渡しを参照してください。

  • オブジェクトに重複するプロパティ名がある場合に、コード ジェネレーターがオブジェクトの定数の畳み込みを実行しようとすると、コード生成が失敗する可能性があります。コード ジェネレーターがオブジェクトに対して定数畳み込みを行うのは、そのオブジェクトが coder.Constant または coder.const で使用されているか、オブジェクトが定数畳み込みが行われた外部関数への入力または出力である場合です。

    次の場合、サブクラスのオブジェクトでプロパティ名が重複します。

    • サブクラスに、スーパークラスのプロパティと同じ名前のプロパティがある。

    • サブクラスが、プロパティに同じ名前を使用する複数のスーパークラスから派生している。

    MATLAB で重複するプロパティ名が許可される場合の詳細については、複数のクラスからのサブクラスの作成を参照してください。

コード生成のためのクラス プロパティの定義

コードを生成するには、MATLAB 環境でコードを実行する場合とは異なる形式でクラスのプロパティを定義しなければなりません。

  • MEX 関数は、プロパティ検証の結果のエラーを報告します。スタンドアロン C/C++ コードは、実行時エラーのレポートを有効にしている場合のみこれらのエラーを報告します。スタンドアロン C/C++ コードでの実行時エラーの検出とレポートを参照してください。スタンドアロン C/C++ コードを生成する前に、入力値のすべての範囲に対して MEX 関数を実行してプロパティの検証をテストすることをお勧めします。

  • プロパティを定義した後は、それを互換性のない型に割り当てないでください。プロパティは、拡大を試みてから使用してください。

    コード生成用にクラス プロパティを定義する際は、変数を定義するときと同様のことを考慮に入れてください。MATLAB 言語では、変数は自身のクラス、サイズまたは実数/複素数を実行時に動的に変更できるため、同じ変数を使用してさまざまなクラス、サイズまたは実数/複素数の値を保持することができます。C および C++ は静的なデータ型を使用します。コード ジェネレーターが変数を使用する前に変数の型を判定するためには、各変数への完全な割り当てが行われている必要があります。同様に、プロパティを使用する前に、プロパティのクラス、サイズ、実数/複素数を明示的に定義しなければなりません。

  • 初期値:

    • プロパティに明示的な初期値が存在しない場合、コード ジェネレーターは、コンストラクターの先頭で初期値が未定義であると認識します。コード ジェネレーターは、既定設定で空の行列を代入しません。

    • プロパティに初期値が存在せず、コード ジェネレーターによってそのプロパティをはじめて使用する前に代入されているかが判定できなかった場合、コンパイル エラーが発生します。

    • System object については、調整不可能なプロパティが構造体の場合、構造体に対して完全な代入を行なわなければなりません。添字を使った部分的な代入はできません。

      たとえば、調整不可能なプロパティには以下のような代入ができます。

      mySystemObject.nonTunableProperty=struct('fieldA','a','fieldB','b');
      

      以下のような部分的な代入はできません。

      mySystemObject.nonTunableProperty.fieldA = 'a';
      mySystemObject.nonTunableProperty.fieldB = 'b';

    • coder.varsize はクラス プロパティではサポートされていません。

    • プロパティの初期値がオブジェクトの場合、プロパティは定数でなければなりません。プロパティを定数にするには、プロパティ ブロックで Constant 属性を宣言します。次に例を示します。

      classdef MyClass 
          properties (Constant) 
              p1 = MyClass2; 
          end 
      end 

    • MATLAB では、クラスの読み込み時にクラスの初期値を計算してからコード生成を行います。MATLAB クラス プロパティの初期化で永続変数を使用すると、クラスの読み込み時に計算される永続変数の値は MATLAB に属します。この値はコード生成時に使用される値ではありません。coder.target を MATLAB クラス プロパティの初期化で使用した場合、coder.target('MATLAB')true (1) を返します。

  • 動的メモリ割り当てが有効になっている場合、コード生成ではハンドル クラスに対して可変サイズのプロパティをサポートします。動的メモリ割り当てを使用しないと、可変サイズのプロパティをもつハンドル クラスのコードは生成できません。

  • プロパティは定数で、その値がオブジェクトの場合、そのオブジェクトのプロパティの値を変更できません。たとえば、次の場合を仮定します。

    • objmyClass1 のオブジェクトです。

    • myClass1 には、myClass2 のオブジェクトである定数プロパティ p1 があります。

    • myClass2 にはプロパティ p2 があります。

    コード生成は、以下のコードをサポートしていません。

    obj.p1.p2 = 1;

基本クラス コンストラクターの呼び出し

クラス コンストラクターに基底クラスのコンストラクターの呼び出しが含まれている場合、その呼び出しは、forifreturnswitch または while ステートメントよりも前に位置しなければなりません。

たとえば、クラス B をクラス A に基づいて次のように定義したとします。

classdef B < A
    methods
        function obj = B(varargin)
            if nargin == 0
                a = 1;
                b = 2;
            elseif nargin == 1
                a = varargin{1};
                b = 1;
            elseif nargin == 2
                a = varargin{1};
                b = varargin{2};
            end
            obj = obj@A(a,b);
        end    
        
    end
end

A の基底クラス コンストラクターの呼び出しの前に B のクラス定義で if ステートメントが使われているため、関数 callB のコードを生成できません。

function [y1,y2] = callB
x = B;
y1 = x.p1;
y2 = x.p2;
end

しかし、以下のようにクラス B を定義すれば、callB のコードを生成できます。

classdef B < A
    methods
        function obj = NewB(varargin)
            [a,b] = getaandb(varargin{:});
            obj = obj@A(a,b);
        end
        
    end
end

function [a,b] = getaandb(varargin)
if nargin == 0
    a = 1;
    b = 2;
elseif nargin == 1
    a = varargin{1};
    b = 1;
elseif nargin == 2
    a = varargin{1};
    b = varargin{2};
end
end

サポートされない組み込みの MATLAB クラスからの継承

組み込みの MATLAB クラスから継承したクラスのコードは生成できません。たとえば、次のクラスのコードは生成できません。

classdef myclass < double