2013-02-10 13 views
7

Mam enum tak:get ciąg wyliczenia - Matlab koder

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

mogę dostać 'ciąg znaków reprezentujący element' jak to:

char(bla_type.bla_one) 

=>

bla_one 

Niestety, program matlab nie lubi tego. Czy są jakieś alternatywy?

+0

Czy koniecznie musisz ją dziedziczyć Int32? W przeciwnym razie możesz dodać właściwość o nazwie (która jest brzydka, tak, ale może działać). – gzm0

Odpowiedz

0

Wypróbuj [~,s]=enumeration('bla_type'). Otrzymasz tablicę komórek zawierającą nazwy elementów w s. Tak więc bla_one będzie w s{1}. Nie wiem jednak, czy jest to obsługiwane przez kodek MATLAB.

2

W tym celu nie ma eleganckiego wbudowanego kodera; wyliczony typ staje się standardowym wyliczeniem w C, a funkcja enumeration w MATLAB jest niedostępna w programie Koder. Najprostszym, ale nieprzyjemnym sposobem na to jest utworzenie funkcji za pomocą instrukcji switch z ręcznie zapełnionymi nazwami łańcuchów. To nie jest miłe, ponieważ teraz musisz zachować nazwiska w dwóch miejscach.

Jednak jednym ze sposobów, który działa dobrze, jest użycie jednej z bardziej zaawansowanych funkcji programu Coder: coder.const.

Rozwiązaniem jest posiadanie funkcji, która tworzy tabelę elementów wyliczeniowych i ich wartości. Ta funkcja nie może zostać skompilowana, ale jest wywoływana podczas kompilacji w celu zbudowania tabeli odnośników w wynikowym kodzie C. Możemy użyć tej tablicy odnośników w funkcji kompatybilnej z koderem, aby uzyskać dane.

Wyobraź mamy takiego typu wyliczeniowego (w someenum.m):

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

również wtedy funkcję build-time o nazwie '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 

Kiedy buildsomeenum2name jest wywoływana w MATLAB-u, tworzy tablicę nazw łańcuchów wszystkich elementów wyliczonego typu i kolejną listę wektorową ich wartości numerycznych w tej samej kolejności.

Oto najfajniejsza część. Program MATLAB Coder może oceniać funkcje w czasie kompilacji i przekształcać je w stałe. Stałe te stają się literałami w wynikowym kodzie C, a nie rzeczywistym kodem. Ponieważ funkcje są obliczane w czasie kompilacji, informacje wyliczeniowe są umieszczane w ładnej tabeli, dlatego jeśli stworzymy funkcję wyszukiwania zgodną z Koderem, możemy jej użyć do przekonwertowania typów elementów na ciąg znaków. Zadzwonimy tę funkcję „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 

Funkcja ta korzysta z komendy coder.const do oceny buildsomeenum2name w czasie kompilacji i tworzenia tabel przeglądowych. Musimy poinstruować Coder, aby nie próbował kompilować buildsomeenum2name, więc użyj polecenia coder.extrinsic, aby powiedzieć, aby zignorować tę funkcję. Następnie someenum2name może wyszukać indeks dla ciągu i wyciągnąć go (deblank jest używany, ponieważ łańcuchy w tablicy mają końcowe 0, które należy wyciągnąć.) Funkcja someenum2name może być wywołana zarówno w obrębie skompilowanego kodu MATLAB jak i kodera.

Ta metoda powoduje, że wszystko jest zsynchronizowane, więc jeśli kiedykolwiek dodasz nowego członka do enum lub zmienisz je, koder.Funkcja const sprawi, że wartości zostaną przebudowane w kodzie wyjściowym, tak aby someenum2name działało.

W wierszu poleceń, to wygląda:

>> someenum2name(someenum.No_thing) 
ans = 
No_thing