7

私は次のような列挙型を持っています:

classdef(Enumeration) bla_type < int32
    enumeration
        bla_one(1)
        bla_2(2)
    end
end

次のように「要素の文字列表現」を取得できます。

char(bla_type.bla_one)

=>

bla_one

残念ながら、matlab コーダーはこれを好みません。代替手段はありますか?

4

2 に答える 2

2

Coder には、これを行うための洗練された組み込みの方法はありません。列挙型は C の標準列挙型になり、enumerationMATLAB の関数は Coder では使用できません。これを行うための最も簡単ですが不快な方法は、手動で入力された文字列名を使用して switch ステートメントを使用して関数を作成することです。2 つの場所で名前を維持する必要があるため、これは良くありません。

ただし、うまく機能する 1 つの方法は、Coder のより強力な機能の 1 つである coder.const を使用することです。

解決策は、列挙メンバーとその値のテーブルを作成する関数を用意することです。この関数自体はコンパイルできませんが、結果の C コードでルックアップ テーブルを作成するためにコンパイル中に呼び出されます。このルックアップ テーブルを Coder 互換関数で使用して、データを取得できます。

次のような列挙型があるとします (someenum.m 内):

classdef someenum < int32 %#codegen
    enumeration
        First_thing (0)
        Second_thing (2)
        Another_thing (3)
        No_thing (4000)
    end
end

また、「buildsomeenum2name.m」と呼ばれるビルド時関数もあります。

function [namearray, memberidx] = buildsomeenum2name
%BUILDSOMEENUM2NAME Compile-time creation of lookup table for someenum 
% THIS FUNCTION IS NOT CODER COMPATIBLE, BUT IS CALLED DURING COMPILE
% TO CREATE A LOOKUP TABLE.

[members, names]=enumeration('someenum');

maxlen = 0;
for i=1:numel(names)
    maxlen = max(maxlen, numel(names{i}));
end

namearray = char(zeros(numel(names), maxlen));
for i=1:numel(names)
    namearray(i, 1:numel(names{i})) = names{i};
end

memberidx =  int32(members); %#ok<NASGU>

end

buildsomeenum2nameMATLAB で呼び出されると、列挙型のすべてのメンバーの文字列名の配列と、それらの数値の別のベクトル リストを同じ順序で作成します。

これがクールな部分です。MATLAB Coder はビルド時に関数を評価し、それらを定数に変換できます。これらの定数は、実際のコードではなく、結果の C コードではリテラルになります。関数はビルド時に評価されるため、列挙情報は適切なテーブルに入れられます。そのため、Coder 互換のルックアップ関数を作成すると、それを使用してメンバー型を文字列に変換できます。この関数を「someenum2name.m」と呼びます。

function name = someenum2name(enum) %#codegen
%SOMEENUM2NAME Get the string name of an enumerated type

% The following line loads namearray and memberidx with constant arrays
coder.extrinsic('buildsomeenum2name');
[namearray, memberidx] = coder.const(@buildsomeenum2name);

% First find the index of the enumerated type in the memberidx vector

index = find(memberidx==int32(enum));
if isempty(index)
    name = 'UNKNOWN';
    return;
end

name = deblank(namearray(index,:));

end

この関数は、coder.constコマンドを使用buildsomeenum2nameしてコンパイル時に評価し、ルックアップ テーブルを作成します。Coder に をコンパイルしないように指示する必要buildsomeenum2nameがあるため、コマンドを使用しcoder.extrinsicて関数を無視するように指示します。次にsomeenum2name、文字列のインデックスを検索して抽出できます (配列内の文字列には、抽出する必要がある末尾の 0 があるため、deblank が使用されます)。この関数someenum2nameは、MATLAB 内と Coder コンパイル コード内の両方で呼び出すことができます。

このメソッドはすべての同期を維持するため、enum に新しいメンバーを追加したり再配置したりする場合、coder.const 関数は値が出力コードで再構築され、someenum2name が機能することを確認します。

コマンド ラインでは、次のようになります。

>> someenum2name(someenum.No_thing)
ans =
No_thing
于 2015-04-14T05:08:14.980 に答える