メインコンテンツ

MATLAB クラスに対応する C++ クラスの生成

C++ コードを生成する場合、コード ジェネレーターの既定の動作では、MATLAB® コード内のクラスに対応する C++ クラスが生成されます。これには、値クラス、ハンドル クラス、System object などのすべての MATLAB クラスが含まれます。

コード ジェネレーターの既定の動作を変更して、MATLAB クラスに対応する構造体を生成できます。既定の動作を変更するには、次のいずれかの方法を使用します。

  • コード構成オブジェクトで、TargetLang'C++' に、CppPreserveClassesfalse に設定します。

  • [コード生成設定] ダイアログ ボックスで、[言語] パラメーターを [C++] に設定し、[MATLAB クラスから C++ クラスを生成] チェック ボックスをオフにします。

MATLAB クラスの C++ クラスへのマッピング

コード ジェネレーターは、MATLAB クラスを C++ クラスにマッピングする際に特定のルールに従います。

  • MATLAB のクラス コンストラクターは init メソッドにマッピングされています。クラスのインスタンスが作成されると、生成されたコードによって init メソッドが明示的に呼び出されます。

  • 多くの場合、MATLAB でプライベートとして設定されているクラス メンバーは、生成された C++ コードでもプライベートとして設定されます。

  • MATLAB の静的メソッドは C++ 静的メソッドにマッピングされています。

  • 生成されたコードでは、オブジェクトを変更しないメソッドは const 修飾子でマークされます。

例: プライベート メンバーとパブリック メンバーをもつハンドル クラスのコード生成

この例では、コード ジェネレーターで MATLAB クラスを C++ クラスにマッピングする際のルールがどのように適用されるかを示します。

ハンドル クラス MyClass について考えます。

classdef MyClass < handle
    properties
        publicProp = 1;
    end
    properties(Access = private)
        privateProp
    end
    methods
        function obj = MyClass(value)
            obj.privateProp = value;
        end
        function publicMethod(obj,value)
            obj.privateMethod(value);
        end
        function res = calculateSomeValue(obj)
            res = obj.publicProp*obj.privateProp;
        end
    end
    methods (Access = private)
        function privateMethod(obj,value)
            obj.publicProp = obj.publicProp + value;
            obj.privateProp = obj.privateProp + obj.doubleThisValue(value);
        end
    end
    methods(Static)
        function res = doubleThisValue(val)
            res = 2 * val;
        end
    end
end

MyClass を使用する MATLAB 関数 useMyClass を定義します。

function out = useMyClass(x,y)
obj = MyClass(x);
obj.publicMethod(y);
out = obj.calculateSomeValue;
end

useMyClass の C++ スタティック ライブラリを生成します。入力引数を double のスカラーとして指定します。コード生成構成プロパティ InlineBetweenUserFunctions'Readability' に設定します。

cfg = coder.config('lib');
cfg.TargetLang = 'C++';
cfg.InlineBetweenUserFunctions = 'Readability';
codegen -config cfg useMyClass -args {0,0} -report
Code generation successful: View report

コード生成レポートを開き、生成されたコードを検査します。ファイル useMyClass.cpp には、生成された C++ 関数が含まれています。

double useMyClass(double x, double y)
{
  MyClass obj;
  obj.init(x);
  obj.publicMethod(y);
  return obj.calculateSomeValue();
}

ファイル MyClass.h には、生成された C++ クラス MyClass の定義が含まれています。

class MyClass {
public:
  MyClass *init(double b_value);
  void publicMethod(double b_value);
  static double doubleThisValue(double val);
  double calculateSomeValue() const;
  double publicProp;

private:
  double privateProp;
};

次の表に、useMyClass の C++ コードの生成にコード ジェネレーターのマッピング ルールがどのように適用されるかを示します。

ルールコード スニペット

MATLAB のクラス コンストラクターは init メソッドにマッピングされています。クラスのインスタンスが作成されると、生成されたコードによって init メソッドが明示的に呼び出されます。

ファイル MyClass.cpp には init の定義が含まれています。

MyClass *MyClass::init(double b_value)
{
  MyClass *obj;
  obj = this;
  obj->publicProp = 1.0;
  obj->privateProp = b_value;
  return obj;
}

多くの場合、MATLAB でプライベートとして設定されているクラス メンバーは、生成された C++ コードでもプライベートとして設定されます。

場合によっては、生成された C++ コードにパブリック メソッドをインライン化すると、生成されたコードで MATLAB コードのプライベート プロパティがパブリック プロパティに変更され、データのカプセル化が中断されます。たとえば、オブジェクトのプライベート プロパティ prop を使用するパブリック メソッド myMethod がエントリポイント関数によって呼び出されるとします。生成されたコードに myMethod をインライン化する場合、プロパティ prop はオブジェクトの外部から認識されなければならず、パブリック プロパティに変更されなければなりません。

この発生を制限するために、コード ジェネレーターでは、次の場合にパブリック メソッドに対して特別なインライン化規則が使用されます。

  • コード構成プロパティ InlineBetweenUserFunctions または MATLAB Coder™ アプリにおける同等のコード生成設定 [ユーザー関数間のインライン]'Readability' に設定されている場合、コード ジェネレーターはクラス定義の外部にあるパブリック メソッドの呼び出しをインライン化しません。

次の場合は、通常の関数とパブリック メソッドの両方に同じインライン化規則が適用されます。

  • 関数またはメソッドが、coder.inlineCall または coder.nonInlineCall を使用して呼び出される。この呼び出しにより、関数本体内の coder.inline 命令と、グローバル インライン化設定がオーバーライドされます。

  • 関数またはメソッドの本体に明示的な coder.inline('always') 命令または coder.inline('never') 命令が含まれている。この命令により、グローバル インライン化設定がオーバーライドされます。

  • コード構成プロパティ InlineBetweenUserFunctions または MATLAB Coder アプリにおける同等のコード生成設定 [ユーザー関数間のインライン]'Never''Speed' または 'Always' に設定されている。

  • メソッドの呼び出しが同じクラスの別のメソッド内にある。

生成コードのパフォーマンスと可読性を微調整するためのインライン化の制御を参照してください。

生成された C++ クラス MyClass の定義は次のとおりです。

class MyClass {
public:
  MyClass *init(double b_value);
  void publicMethod(double b_value);
  static double doubleThisValue(double val);
  double calculateSomeValue() const;
  double publicProp;

private:
  double privateProp;
};

すべてのデータおよびメンバー関数の可視性は、MATLAB と生成されたコードの間で維持されます。

プライベート メソッド privateMethod はこの定義には表示されません。privateMethod はファイル MyClass.cpp にある publicMethod の定義でインライン化されています。

void MyClass::publicMethod(double b_value)
{
  publicProp += b_value;
  privateProp += MyClass::doubleThisValue(b_value);
}

MATLAB の静的メソッドは C++ 静的メソッドにマッピングされています。

静的メソッド doubleThisValue の生成されたコードには次のシグネチャがあります。

double MyClass::doubleThisValue(double val)
{
  return 2.0 * val;
}

生成されたコードでは、オブジェクトを変更しないメソッドは const 修飾子でマークされます。

パブリック メソッド calculateSomeValue はオブジェクトを変更しません。生成されたメソッドには次のシグネチャがあります。

double MyClass::calculateSomeValue() const
{
  return publicProp * privateProp;
}

その他の使用上の注意および制限

MATLAB クラスから C++ クラスを生成するときに適用されるその他の使用上の注意および制限を次に示します。

  • MyClassName のクラスのプロトタイプはヘッダー ファイル MyClassName.h に含まれています。クラスのメソッドの実装はファイル MyClassName.cpp に含まれています。

  • 生成されたコードでは、クラス階層はフラットになります。たとえば、MATLAB コードで、クラス MySubClass がクラス MySuperClass から継承されるとします。生成された C++ コードでは、クラス MySubClass とクラス MySuperClass に継承関係はありません。生成されたコードでは、MySuperClass のプロパティおよびメソッドが MySubClass の定義で再現されます。

  • MATLAB クラスがそのプロパティに対して異なる型を使用する場合、コード ジェネレーターは型の使用ごとに個別の C++ クラスを生成します。

  • MATLAB クラス メンバーの GetAccess 属性と SetAccess 属性が異なる場合、生成されたクラスの対応するメンバーは、2 つの属性のうち許容性が高い方をもちます。たとえば、プロパティ prop が属性 (GetAccess = public, SetAccess = private) をもつ場合、生成されたコードでは、prop はパブリック プロパティとして定義されます。

  • MATLAB クラスに対応する C++ クラスを含むスタンドアロン コードを生成しようとしたときに、以下の両方の条件に該当する場合は、警告メッセージが表示されることがあります。

    • コード構成オブジェクトで MultiInstanceCode プロパティを true に設定するか、[再呼び出し可能なコードを生成] パラメーターをオンにすることで、再呼び出し可能なコードを生成するように選択した。

    • MATLAB コード内のクラスのデストラクターが永続変数をもつか、永続変数を宣言して使用する別の関数を呼び出す。

    このような状況で、MATLAB クラスに対応する C++ クラスを含むコードを生成するには、MultiInstanceCode プロパティを False に設定するか、[再呼び出し可能なコードを生成] パラメーターのチェック ボックスをオフにします。

参考

| | | | |

トピック