CODESYS форум

Добро пожаловать на официальный форум CODESYS
Deutsche Version English version russian version 
Текущее время: Чт май 25, 2017 7:54 am

Часовой пояс: UTC+01:00




Начать новую тему  Ответить на тему  [ 3 сообщения ] 
Автор Сообщение
 Заголовок сообщения: Динамические массивы
СообщениеДобавлено: Сб ноя 01, 2014 2:27 pm 
Не в сети

Зарегистрирован: Вс авг 14, 2011 8:27 am
Сообщения: 13
Доброго времени суток!

По работе у меня чаще всего однотипные объекты, которые различаются только количеством сигналов. В общем-то шаблон типового проекта есть, но надоедает каждый раз ручками проставлять границы массивов, связи между объектами и т.д. Давно задумывался о сабже и вот выдалась пара свободных дней. Хочу предложить на суд общественности вариант реализации:

Сам контейнер:
FUNCTION_BLOCK TCollection IMPLEMENTS ICollection
VAR_INPUT
//идентификатор коллекции для системы
sCollectionName: STRING(10);
//размер элемента коллекции
udiObjectSize: UDINT;
END_VAR
VAR
//указатель на начало области памяти
hMemPtr: POINTER TO BYTE := 0;
//количество элементов в коллекции
iCount: INT;
//результат выполнения операции
hResult: SysTypes.RTS_IEC_RESULT;
//флаг ошибки
xError: BOOL;
//максимальное количество элементов в коллекции
udiCapacity: UDINT := 0;
END_VAR
VAR CONSTANT
//максимальное значение, на которое можно увеличивать память
byMaxGrowSize: BYTE := 16;
END_VAR

(*добавляет элемент в коллекцию*)
METHOD AddObject
VAR_INPUT
(*интерфейс добавляемого объекта*)
pObject : IObject;
END_VAR
VAR
//адрес элемента в памяти
hMem: POINTER TO IObject;
END_VAR
IF (hMemPtr = 0) OR (udiCapacity = iCount) THEN
Grow();
END_IF
hMem := hMemPtr + iCount * udiObjectSize;
hMem^ := pObject;
iCount := iCount + 1;

(*возвращает запрошенный элемент коллекции*)
METHOD GetObject
VAR_INPUT
(*индекс элемента в коллекции*)
udiIndex : UDINT;
END_VAR
VAR_IN_OUT
//интерфейс объекта
pObject: IObject;
END_VAR
VAR
//указатель на память
hMem: POINTER TO IObject;
END_VAR
IF (iCount <= 0) OR (hMemPtr = 0) THEN
RETURN;
END_IF
hMem := hMemPtr + udiIndex * udiObjectSize;
pObject := hMem^;

//выделяет память под элементы коллекции
METHOD PRIVATE Grow
VAR
udiNeedSize: UDINT;
END_VAR
//сбрасываем ошибку
xError := FALSE;
//рассчитываем необходимый размер памяти
udiNeedSize := (iCount + byMaxGrowSize) * udiObjectSize;
IF hMemPtr = 0 THEN
hMemPtr := SysMem.SysMemAllocData(szComponent := sCollectionName, udiSize := udiNeedSize, pResult := ADR(hResult));
ELSE
hMemPtr := SysMem.SysMemReallocData(szComponent := sCollectionName, pMemory := hMemPtr, udiSize := udiNeedSize, pResult := ADR(hResult));
END_IF
xError := hResult <> 0;
udiCapacity := udiCapacity + byMaxGrowSize;

Использование:
PROGRAM PLC_PRG
VAR
obj: TOpticalSensor1;
objptr: POINTER TO TOpticalSensor1;
coll: TCollection;
ww: WORD := 1;
count: INT;
END_VAR
objptr := __NEW(TOpticalSensor1);
objptr^(wID := ww);
ww := ww + 1;
coll.AddObject(pObject := objptr^);

FOR count := 0 TO coll.Count() - 1 DO
coll.GetObject(udiIndex := count, pObject := objintf);
IF objintf <> 0 THEN
objintf.Execute();
END_IF
END_FOR

Вот как-то так. Нарисовано на коленке, в перерывах между танками и евой. Жду критики.


Вернуться к началу
 Заголовок сообщения: Re: Динамические массивы
СообщениеДобавлено: Пт ноя 14, 2014 9:29 pm 
Не в сети

Зарегистрирован: Вс авг 14, 2011 8:27 am
Сообщения: 13
Неужели никто ничего не скажет?


Вернуться к началу
 Заголовок сообщения: Re: Динамические массивы
СообщениеДобавлено: Вт дек 23, 2014 10:20 am 
Не в сети

Зарегистрирован: Чт дек 01, 2011 8:24 am
Сообщения: 21
А где проверка корректности индекса в GetObject? Ещё в подобных классах принята возможность задавать начальный размер. По вкусу можно сделать размер опережающего наращивания зависимым от него. Ну и без удаления не труъ)


Вернуться к началу
Показать сообщения за:  Поле сортировки  
Начать новую тему  Ответить на тему  [ 3 сообщения ] 

Часовой пояс: UTC+01:00


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 2 гостя


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Limited
Русская поддержка phpBB