MATLAB Coder массив структур с динамическим размером

Я пытаюсь использовать динамически растущий массив структур в фрагменте кода, который должен быть преобразован в C с помощью Coder:

Я инициализирую структуру, а затем объявляю ее переменный размер полей для кодировщика, а затем продолжаю наращивать структуру. Обратите внимание, что я упростил этот пример, чтобы облегчить читаемость сгенерированного кода, поэтому причина, по которой я использую массив структур, не очевидна из этого примера.

MATLAB:

function [ events ] = testArraysOfStructs( data)
//%#codegen

ii=1;
events = struct('typ'   ,int32(0),...
                'title' ,int32(1),...
                'value' ,double(0),...
                'sta'   ,int32(2),...
                'end'   ,int32(3));

coder.varsize('events','events.typ','events.title','events.value','events.sta','events.end','events.title')

for n=1:length(data.temperatur_spikes_daily)

    events(ii).typ      = int32(101);
    events(ii).title    = int32(1234);
    events(ii).value    = double(1234);
    events(ii).sta      = int32(4321);
    events(ii).end      = int32(3412);

    ii = length(events)+1;
end
end

Проблема в том, что в сгенерированном коде переменная ii исчезает, и данные непрерывно записываются в одни и те же элементы массива структуры без учета количества итераций цикла, который должен увеличивать ее.

C:

void testArraysOfStructs(const struct0_T *data, struct1_T events_data[], int
  events_size[2])
{
  struct1_T r0;
  int n;
  r0.typ.size[0] = 1;
  r0.typ.size[1] = 1;
  r0.typ.data[0] = 0;
  r0.title.size[0] = 1;
  r0.title.size[1] = 1;
  r0.title.data[0] = 1;
  r0.value.size[0] = 1;
  r0.value.size[1] = 1;
  r0.value.data[0] = 0.0;
  r0.sta.size[0] = 1;
  r0.sta.size[1] = 1;
  r0.sta.data[0] = 2;
  r0.end.size[0] = 1;
  r0.end.size[1] = 1;
  r0.end.data[0] = 3;
  events_size[0] = 1;
  events_size[1] = 1;
  events_data[0] = r0;
  for (n = 0; n < data->temperatur_spikes_daily->size[0]; n++) {
    events_data[0].typ.size[0] = 1;
    events_data[0].typ.size[1] = 1;
    events_data[0].typ.data[0] = 101;
    events_data[0].title.size[0] = 1;
    events_data[0].title.size[1] = 1;
    events_data[0].title.data[0] = 1234;
    events_data[0].value.size[0] = 1;
    events_data[0].value.size[1] = 1;
    events_data[0].value.data[0] = 1234.0;
    events_data[0].sta.size[0] = 1;
    events_data[0].sta.size[1] = 1;
    events_data[0].sta.data[0] = 4321;
    events_data[0].end.size[0] = 1;
    events_data[0].end.size[1] = 1;
    events_data[0].end.data[0] = 3412;
  }
}

Я полагаю, у меня есть ошибка при объявлении структуры динамической, но, к сожалению, документация содержит только примеры объявления либо стандартных динамических массивов, либо предварительного выделения размера массива структур, хотя динамическое изменение размеров упоминается как поддерживаемое. Любая помощь в этом будет принята с благодарностью.


person sobek    schedule 17.09.2014    source источник


Ответы (1)


Краткий ответ: увеличение массива путем индексации одного за концом - это не поддерживается с помощью Coder.

Таким образом, ваш цикл, который увеличивает размер events на каждой итерации, не поддерживается для Coder. Вы можете использовать:

function [ events ] = foo(data)
%#codegen

events = struct('typ'   ,int32(0),...
                'title' ,int32(1),...
                'value' ,double(0),...
                'sta'   ,int32(2),...
                'end'   ,int32(3));

for n = 1:length(data.temperatur_spikes_daily)
    events = [events, struct('typ'   ,int32(101),...
                'title' ,int32(1234),...
                'value' ,double(1234),...
                'sta'   ,int32(4321),...
                'end'   ,int32(3412))];
end

or:

function [ events ] = foo(data)
%#codegen
% Allocate events
s = struct('typ'   ,int32(0),...
    'title' ,int32(1),...
    'value' ,double(0),...
    'sta'   ,int32(2),...
    'end'   ,int32(3));
events = coder.nullcopy(repmat(s, 1, length(data.temperatur_spikes_daily)));

% Populate values of events
for n = 1:numel(events)
    events(n).typ      = int32(101);
    events(n).title    = int32(1234);
    events(n).value    = double(1234);
    events(n).sta      = int32(4321);
    events(n).end      = int32(3412);
end

вместо.

Если вы сгенерируете функцию MEX из исходного кода, а не автономного кода, и запустите эту функцию MEX в MATLAB, вы получите ошибку:

Index exceeds matrix dimensions.  Index value 2 exceeds valid range [1-1] of array events.

Error in foo (line 15)
    events(ii).typ      = int32(101);

Генерация и запуск функции MEX - лучший способ проверить, что ваш код MATLAB использует конструкции, которые поддерживаются для Coder.

person Ryan Livingston    schedule 17.09.2014
comment
Думаю, я неправильно понял, что они писали о динамических полях массивов структур. Похоже, ваше первое предложение может сработать для меня. Я приму ответ, как только попробую. - person sobek; 17.09.2014