最新のリリースでは、このページがまだ翻訳されていません。 このページの最新版は英語でご覧になれます。
MATLAB® クラスの効率の良いスタンドアロン コードを生成するには、MATLAB 環境でコードを実行する場合とは異なる方法でクラスを使用しなければなりません。
相違点 | 詳細 |
---|---|
制限された一部の言語機能 | 言語制約 |
制限された一部のコード生成機能 | クラスと整合性がないコード生成機能 |
クラス プロパティの定義 | コード生成のためのクラス プロパティの定義 |
ハンドル クラスの使用 | |
基底クラス コンストラクターの呼び出し | 基本クラス コンストラクターの呼び出し |
MATLAB ハンドル オブジェクトを含むグローバル変数はコード生成に対応していません。 | N/A |
組み込みの MATLAB クラスからの継承はサポートされていません。 | サポートされない組み込みの MATLAB クラスからの継承 |
プロパティやメソッドなどの一般的なクラスの機能に対してはコード生成がサポートされていますが、以下のようなサポートされていない高度な機能が数多くあります。
イベント
リスナー
オブジェクトの配列
再帰データ構造体
リンク付きリスト
Trees
グラフ
コンストラクターにおける入れ子関数
オーバーロードが可能な演算子 subsref
、subsassign
、subsindex
MATLAB では、クラスで独自のバージョンの subsref
、subsassign
、subsindex
メソッドを定義できます。コード生成では、これらのメソッドの独自の定義をもつクラスはサポートされていません。
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)
を返します。
動的メモリ割り当てが有効になっている場合、コード生成ではハンドル クラスに対して可変サイズのプロパティをサポートします。動的メモリ割り当てを使用しないと、可変サイズのプロパティをもつハンドル クラスのコードは生成できません。
プロパティは定数で、その値がオブジェクトの場合、そのオブジェクトのプロパティの値を変更できません。たとえば、次の場合を仮定します。
obj
は myClass1
のオブジェクトです。
myClass1
には、myClass2
のオブジェクトである定数プロパティ p1
があります。
myClass2
にはプロパティ p2
があります。
コード生成は、以下のコードをサポートしていません。
obj.p1.p2 = 1;
クラス コンストラクターに基底クラスのコンストラクターの呼び出しが含まれている場合、その呼び出しは、for
、if
、return
、switch
または 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 クラスから継承したクラスのコードは生成できません。たとえば、次のクラスのコードは生成できません。
classdef myclass < double