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
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