2013-02-10 2 views
7

У меня есть перечисление, как это:прибудет строка перечислимого - MATLAB кодировщик

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

я могу получить 'строкового представления элемента', как это:

char(bla_type.bla_one) 

=>

bla_one 

К сожалению, кодер Matlab не нравится. Есть ли альтернативы?

+0

ли вам абсолютно необходимо, чтобы наследовать от int32? В противном случае вы можете добавить свойство с именем в нем (что уродливо, да, но может работать). – gzm0

ответ

0

Попробуйте [~,s]=enumeration('bla_type'). Вы получаете массив ячеек строк, содержащих имя элементов в s. Таким образом, bla_one будет в s{1}. Не знаю, поддерживается ли это кодов MATLAB.

2

В 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 
Смежные вопросы