Main Content

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

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

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

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

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

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

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

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

動的に割り当てられた配列を使用する C++ 関数インターフェイスの例

次の表に、生成された C++ コード内における動的な配列表現の代表的な例を 2 つ示します。次の節では、生成されたコードに動的な配列を実装する coder::array テンプレートの定義について説明します。

アルゴリズムの説明と配列サイズ

MATLAB Function

生成された C++ 関数インターフェイス

30,000 要素で制限される可変サイズの行ベクトルに 1 をプッシュします。

可変サイズ、しきい値内に制限されません。

function B = create_vec2 %#codegen
B = zeros(1,0);
coder.varsize('B',[1 30000],[0 1]);
for i = 1:500
    if round(rand)
        B = [1 B];
    end
end
void create_vec2(coder::array<double, 2U> &B)

制限されていない整数入力により決定されるサイズの配列を作成します。

コンパイル時に不明です。

function y = create_vec3(n) %#codegen
y = int8(ones(1,n));
void create_vec3(double n, coder::array<signed char, 2U> &y)

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++ コードの生成

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

function Y = xTest1(X, A)
Y = X;
for i = 1:numel(X)
    Y(i) = X(i) + A;
end

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

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

#include<iostream>
#include<coder_array.h>
#include<xTest1.h>

int main(int argc, char *argv[])
{
    static_cast<void>(argc);
    static_cast<void>(argv);

    coder::array<int32_T, 2> myArray;
    myArray.set_size(1, 100);
    for (int i = 0; i < myArray.size(1); i++) {
        myArray[i] = i;
    }

    coder::array<int32_T, 2> myResult;
    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;
}

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

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

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

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

次のスクリプトを実行してコードを生成します。'C:\work' を現在の作業フォルダーへのパスに置き換えます。

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

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

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

文字ベクトル 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!'];

現在の作業フォルダー内のファイル xStringTest_main.cpp で C++ main 関数を定義します。この main 関数は std::vector を使用して、生成された C++ 関数 xStringTest に渡す char_T 要素のベクトル vec を宣言します。

#include<iostream>
#include<coder_array.h>
#include<xTest1.h>

int main(int, char *[])
{
    coder::array<char_T, 2> result;
    
    std::vector<char_T> vec;
    vec.resize(10);
    for (size_t i = 0; i < 10; i++) {
        vec[i] = static_cast<char_T>('A' + i);
    }
    
    xStringTest(vec, result);
    
    std::cout << "Result is " << static_cast<std::string>(result) << std::endl;
    
    return 0;
}

次のスクリプトを実行してコードを生成します。'C:\work' を現在の作業フォルダーに置き換えます。

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

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

参考

|

関連するトピック