В Coder нет элегантного встроенного способа, перечислимый тип становится стандартным перечислением в C, а функция enumeration
в MATLAB недоступна в кодере. Самый простой, но неприятный способ сделать это - создать функцию с помощью оператора switch с именами, заполненными вручную. Это не приятно, так как теперь вы должны поддерживать имена в двух местах.
Однако, один из способов, который отлично работает, - использовать одну из более мощных функций Coder: coder.const.
Решение состоит в том, чтобы иметь функцию, которая создает таблицу элементов перечисления и их значений. Сама эта функция не может быть скомпилирована, а, скорее, вызывается во время компиляции для построения таблицы поиска в результирующем C-коде. Мы можем использовать эту таблицу поиска в кодер-совместимой функции для получения данных.
Представьте, что мы имеем перечисляемого типа, как это (в 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
Когда buildsomeenum2name
вызывается в MATLAB, он создает массив строковых имен всех членов перечисляемого типа и другого векторного списка их числовых значений в том же порядке.
Вот и крутая часть. 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
может найти индекс для строки и вытащить ее (deblank используется, потому что строки в массиве имеют завершающие 0, которые необходимо вытащить.) Функция someenum2name
может быть вызвана как внутри MATLAB, так и в кодексе с кодовым кодом.
Этот метод хранит все в синхронизации, поэтому, если вы когда-либо добавляете новый член в перечисление или переставляете их, кодер.const будет следить за тем, чтобы значения были перестроены в выходном коде, так что someenum2name работает.
В командной строке это выглядит следующим образом:
>> someenum2name(someenum.No_thing)
ans =
No_thing
ли вам абсолютно необходимо, чтобы наследовать от int32? В противном случае вы можете добавить свойство с именем в нем (что уродливо, да, но может работать). – gzm0