Main Content

このページの翻訳は最新ではありません。ここをクリックして、英語の最新版を参照してください。

生成された関数インターフェイスでの動的に割り当てられた C++ 配列の使用

ほとんどの場合、配列を受け入れるか配列を返す MATLAB® 関数のコードを生成すると、生成された C/C++ 関数のインターフェイスに配列が含まれます。コンパイル時にサイズが不明な配列、または事前定義されたしきい値を制限が超える配列の場合、生成された配列のメモリはヒープで動的に割り当てられます。それ以外の場合、生成された配列のメモリはスタックで静的に割り当てられます。可変サイズの配列に対するメモリ割り当ての制御を参照してください。

コード生成のターゲット言語として C++ を選択した場合、既定では、動的に割り当てられた配列は生成されたコードに coder::array というクラス テンプレートとして実装されます。動的に割り当てられた配列を生成された C++ 関数と統合するカスタム C++ コードで使用するには、coder::array テンプレートの使用方法を習得してください。

coder::array クラス テンプレートの使用

MATLAB 関数の C++ コードを生成すると、コード ジェネレーターによってビルド フォルダーにヘッダー ファイル coder_array.h が生成されます。このヘッダー ファイルには、名前空間 coder 内のクラス テンプレート array の定義が含まれています。coder::array テンプレートは、生成されたコードに動的に割り当てられた配列を実装します。このテンプレートの宣言は次のとおりです。

template <typename T, int32_T N> class array
配列には T 型の要素が含まれ、その次元数は N です。たとえば、カスタム C++ コードで int32_T 型の要素を含む 2 次元の動的な配列 myArray を宣言するには、次を使用します。

coder::array<int32_T, 2> myArray

動的に割り当てられた配列を生成されたコード (カスタム main 関数など) と統合するカスタム C++ コードで使用するには、coder_array.h ヘッダー ファイルをカスタム .cpp ファイルに含めます。次の表に、カスタム C++ コードで動的な配列を作成して操作するために使用する API を示します。

アクション

手順

int32_T 型の要素を含む動的な配列 myArray を宣言する。myArray の次元数を 2 に設定する。

coder::array テンプレートを使用します。要素の型と次元数を指定します。

coder::array<int32_T, 2> myArray

myArray にメモリを割り当てる。最初の次元のサイズを 1 に、2 番目の次元のサイズを 100 に設定する。

set_size メソッドを使用します。

myArray.set_size(1, 100)

myArray の次元が後で実行時に変化すると、生成されたコードは新しいサイズに基づいてメモリを再割り当てします。

myArray のサイズ ベクトルにアクセスする。

myArray のデータ メンバーである size 配列にアクセスします。たとえば、myArray の 2 番目の次元のサイズにアクセスするには、次を使用します。

myArray.size(1)

動的な配列 myArray にインデックスを付ける。

配列インデックス付けの標準の C++ 構文を使用します。たとえば、myArrayi 番目の要素を i と等しくなるよう設定するには、次を使用します。

myArray[i] = i

また、標準の C++ 構文を使用して多次元配列にインデックスを付けるか、at メソッドを使用することもできます。

myArray[i][j] = i*j;
// You can also use the 'at' function
myArray.at(i,j) = i * j;

変数 coder::array を配列 std::string と配列 std::vector から作成する。

コピー コンストラクターを使用して、配列 coder::array を配列 std::string と配列 std::vector から作成します。たとえば、配列 std::vectorveccoder::array コピーを作成するには、次を使用します。

std::vector<int32_T> vec;
// Create coder::array copy
coder::array<int32, 2> copyArray(vec);

copyArray を、生成コードとプロジェクト間のインターフェイスとして使用します。

次の例では、可変サイズの数値配列と文字配列を受け入れて返す C++ コードの生成方法を説明します。動的に割り当てられた配列をカスタム C++ コードで使用するには、coder_array.h ヘッダー ファイルをカスタム .cpp ファイルに含めます。coder::array クラス テンプレートには、配列メモリの割り当てと解放を実行できるメソッドがあります。

動的サイズの配列である std::vector または std::string の配列と生成コード間のインターフェイスを取ることもできます。これらの配列は、生成された関数への入力としても使用できます。可変サイズの文字ベクトルを受け入れて返す C++ コードの生成を参照してください。

可変サイズの数値配列を受け入れて返す C++ コードの生成

この例では、プロジェクトの coder::array クラス テンプレートを使用するように、生成された main 関数の例をカスタマイズする方法を示します。関連するメソッドについては、上記の表を参照してください。

目的は、int32_T 要素の配列を受け入れて返すことができる xTest1 の C++ 実行可能ファイルを生成することです。配列の最初の次元の大きさを 1 にして、2 番目の次元を制限なしにするとします。

  1. 配列 X を受け入れてその各要素にスカラー A を追加し、結果の配列 Y を返す MATLAB 関数 xTest1 を定義します。

    function Y = xTest1(X, A)
    Y = X;
    for i = 1:numel(X)
        Y(i) = X(i) + A;
    end
  2. xStringTest の初期ソース コードを生成し、xTest1.h をコード生成フォルダーから現在のフォルダーに移動します。次のコマンドを使用します。

    cfg = coder.config('lib'); cfg.TargetLang = 'C++';
    codegen -config cfg -args { coder.typeof(int32(0), [1 inf]), int32(0)} xTest1.m -report

    生成されたコード内の xTest1 の関数プロトタイプは次のとおりです。

    void xTest1(const coder::array<int, 2U> &X, int A, coder::array<int, 2U> &Y)

    上記の関数プロトタイプと互換性のある入力配列と出力配列を指定して、生成コードとのインターフェイスを取ります。

  3. 現在の作業フォルダー内のファイル xTest1_main.cpp で C++ main 関数を定義します。

    この main 関数には、coder::array クラス テンプレートの定義を含むヘッダー ファイル coder_array.h が含まれています。この main 関数は、前の節の表で説明した API を使用して次のアクションを実行します。

    • myArraymyResultint32_T 要素の 2 次元の動的な配列として宣言する。

    • set_size メソッドを使用して、myArray の 2 つの次元のサイズを 1100 に動的に設定する。

    • myResult.size を使用して、myResult のサイズ ベクトルにアクセスする。

    #include<iostream>
    #include<coder_array.h>
    #include<xTest1.h>
    
    int main(int argc, char *argv[])
    {
        static_cast<void>(argc);
        static_cast<void>(argv);
        
        // Instantiate the input variable by using coder::array template
        coder::array<int32_T, 2> myArray;     
        
        // Allocate initial memory for the array
        myArray.set_size(1, 100);             
    
        // Access array with standard C++ indexing
        for (int i = 0; i < myArray.size(1); i++) {
            myArray[i] = i;                   
        }
        
        // Instantiate the result variable by using coder::array template
        coder::array<int32_T, 2> myResult;
    
        // Pass the input and result arrays to the generated function
        xTest1(myArray, 1000, myResult);
    
        for (int i = 0; i < myResult.size(1); i++) {
            if (i > 0) std::cout << " ";
            std::cout << myResult[i];
            if (((i+1) % 10) == 0) std::cout << std::endl;
        }
        std::cout << std::endl;
    
        return 0;
    }
  4. 次のスクリプトを実行してコードを生成します。

    cfg = coder.config('exe'); cfg.TargetLang = 'C++';
    cfg.CustomSource = 'xTest1_main.cpp';
    cfg.CustomInclude = '.';     %current working directory
    codegen -config cfg -args { coder.typeof(int32(0), [1 inf]), int32(0)} xTest1_main.cpp xTest1.m -report

コード ジェネレーターによって現在の作業フォルダーに実行可能ファイル xTest1.exe が生成されます。

可変サイズの文字ベクトルを受け入れて返す C++ コードの生成

この例では、coder::array クラス メソッドを使用して string 配列と生成コード間のインターフェイスを取るように、生成されたメイン ファイルの例をカスタマイズする方法を示します。

この例の main 関数は std::vector を使用して、生成された C++ 関数 xStringTest に渡す char_T 要素のベクトル vec を宣言します。

  1. 文字ベクトル str を受け入れて文字ベクトル 'hello '' world!' の間に str を挿入し、結果を返す MATLAB 関数 xStringTest を定義します。目的は、xStringTest から C++ 実行可能ファイルを生成することです。

    function y = xStringTest(str)
    assert(isa(str, 'char'));
    assert(size(str,1) == 1);
    assert(size(str,2) >= 0);
    y = ['hello ' str ' world!'];
  2. xStringTest のソース コードを生成し、xStringTest.h をコード生成フォルダーから現在の作業フォルダーに移動します。次のコマンドを使用します。

    cfg = coder.config('lib'); cfg.TargetLang = 'C++';
    codegen -config cfg -args {coder.typeof(char('X'), [1 inf])} xStringTest.m -report

    レポートで、生成されたコード内の xStringTest の関数プロトタイプを確認します。

    void xStringTest(const coder::array<char, 2U> &str, coder::array<char, 2U> &y)
    

    上記の関数プロトタイプと互換性のある入力配列と出力配列を指定して、生成コードとのインターフェイスを取ります。

  3. 現在の作業フォルダー内のファイル xStringTest_main.cpp で C++ main 関数を定義します。

    この main 関数では、入力配列を char_T の配列 std::vector として定義します。for ループは、文字値をもつ vec'A' から 'J' に初期化します。この配列は、xStringTest の生成された関数への入力です。関数の出力は、coder::array の変数 result に返されます。

    #include<iostream>
    #include<coder_array.h>
    #include<xStringTest.h>
    
    int main(int, char *[])
    {
        // Instantiate the result variable by using coder::array template
        coder::array<char_T, 2> result;
        
        // Instantiate the input variable by using std::vector
        std::string vec;
    
        // Resize the input to include required values
        vec.resize(10); 
        vec = "ABCDEFGHIJ";
        
        // Pass the input and result arrays to the generated function interface
        xStringTest(vec, result);
        
        //Cast coder::array 'result' variable to std::string to display it
        std::cout << "Result is "; 
        std::cout << static_cast<std::string>(result) << std::endl;
        
        return 0;
    }
    
  4. 次のスクリプトを実行してコードを生成します。

    cfg = coder.config('exe'); cfg.TargetLang = 'C++';
    cfg.CustomSource = 'xStringTest_main.cpp';
    cfg.CustomInclude = '.'; %current working directory
    codegen -config cfg -args {coder.typeof(char('X'), [1 inf])} xStringTest_main.cpp xStringTest.m -report

コード ジェネレーターによって現在の作業フォルダーに実行可能ファイル xStringTest.exe が生成されます。

インターフェイス生成の変更

既定では、生成された C++ コードは、coder::array テンプレートを使用して動的に割り当てられた配列を実装します。代わりに、C スタイルの emxArray データ構造体を使用して動的に割り当てられた配列を実装する C++ コードを生成することもできます。C スタイルの emxArray データ構造体を生成するには、次のいずれかを行います。

  • コード構成オブジェクト (coder.MexCodeConfigcoder.CodeConfig または coder.EmbeddedCodeConfig) 内で DynamicMemoryAllocationInterface パラメーターを 'C' に設定する。

  • MATLAB Coder™ アプリの [メモリ] タブで、[動的メモリ割り当てインターフェイス][C スタイルの EmxArray を使用] に設定する。

C スタイルの emxArray データ構造体を使用して実装する静的に割り当てられた配列と動的に割り当てられた配列の詳細については、生成された関数インターフェイスでの C 配列の使用を参照してください。

参考

|

関連するトピック