OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Суббота, 23 Март, 2019 13:26

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 30 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: NEW в процедуре.
СообщениеДобавлено: Пятница, 02 Сентябрь, 2016 17:35 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1104
Откуда: СССР v2.0 rc 1
Уважаемые коллеги!
Совершенно очевидно, что я не понимаю, как работает такой кусок:
1. Создаю статический указатель на запись.
2. Передаю в процедуру этот указатель, где в процедуре делаю NEW(указатель) и все остальные первоначальные манипуляции.
3. При возврате из процедуры BlackBox ругается на NIL. Т.е. фактически, как мой указатель был инициирован NIL, так и остался.

Подскажите правильный порядок действий. Если это возможно.
Может, как-то разыменование сделать. Или RETURN с указателем через локальный VAR (хотя, на сколько я понимаю, такой указатель будет на стеке?)

Короче, надеюсь только на вас))


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Пятница, 02 Сентябрь, 2016 17:48 
Аватара пользователя

Зарегистрирован: Вторник, 19 Сентябрь, 2006 21:54
Сообщения: 2292
Откуда: Россия, Санкт-Петербург
Код в студию!

Не понятно, что такое "статический указатель".
Не понятно, передаётся ли указатель в процедуру по ссылке или по значению.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Пятница, 02 Сентябрь, 2016 18:12 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1104
Откуда: СССР v2.0 rc 1
Примерно так:
Код:
MODULE a1
TYPE
 tpRecord = POINTER TO RECORD
    a:BYTE
  END;

PROCEDURE Init*(tpr_:tpRecord; a_:BYTE);
BEGIN
  NEW(tpr_);
  tpr_.a:=a_
END Init;

END a1.


Код:
MODULE a2;
IMPORT a1;
VAR
    myVar: a1.tpRecord;

BEGIN
  a1.Init(myVar,0)
END a1.


Подозреваю, что где-то что-то я забыл)) Подставить VAR перед указателем в процедуре?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Пятница, 02 Сентябрь, 2016 18:20 
Аватара пользователя

Зарегистрирован: Суббота, 26 Ноябрь, 2005 02:12
Сообщения: 437
Откуда: Егорьевск
да


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Пятница, 02 Сентябрь, 2016 18:33 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1104
Откуда: СССР v2.0 rc 1
Хорошо. Вопрос в догонку. Я наследую через указатель -- указатель на расширяемую запись.
1. Так можно?
2. Как базовому указателю грамотно NEW устроить?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Пятница, 02 Сентябрь, 2016 18:43 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9099
Откуда: Россия, Орёл
Давайте код, на слух невозможно понять )


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Пятница, 02 Сентябрь, 2016 18:52 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1104
Откуда: СССР v2.0 rc 1
Код:
   TYPE
      tpGrad* = POINTER TO EXTENSIBLE RECORD (mTf.tpFaze)
      END;

PROCEDURE Init(VAR grad_:tpGrad; faze_:BYTE);
BEGIN
  NEW(grad_);
  mTf.Init(grad_.????) (* вот здесь как быть -- не догоняю *)
END Init;


Или здесь наследование не прокатывает?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Пятница, 02 Сентябрь, 2016 19:08 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2257
prospero78 писал(а):
Хорошо. Вопрос в догонку. Я наследую через указатель -- указатель на расширяемую запись.
1. Так можно?
2. Как базовому указателю грамотно NEW устроить?


Вот старый примерчик. Вроде бы он был по книге:
Фримен Э. и др. Паттерны проектирования. Санкт-Петербург: Питер, 2011. 656 с.

Тут не только фабрика, но и еще "нечто" в стиле ББ.
Код:
MODULE MyTest;
   IMPORT  Log;
   
   TYPE
      Animal = POINTER TO ABSTRACT RECORD
         next: Animal
      END;
      Cat = POINTER TO RECORD (Animal) END;
      Dog = POINTER TO RECORD (Animal) END;
      Directory = POINTER TO RECORD
         root: Animal
      END;

   VAR
      dir: Directory;

   PROCEDURE (d: Directory) Add (a: Animal), NEW;
   VAR tmp: Animal;
   BEGIN
      IF d.root = NIL THEN
         d.root := a
      ELSE
         tmp := d.root;
         WHILE tmp.next # NIL DO tmp := tmp.next END;
         tmp.next := a
      END
   END Add;
   
   PROCEDURE (a: Animal) FeedMilk, NEW, ABSTRACT;
   
   PROCEDURE (a: Cat) FeedMilk;
   BEGIN
      Log.String("Mmm!"); Log.Ln;
   END FeedMilk;
   
   PROCEDURE (a: Dog) FeedMilk;
   BEGIN
      Log.String("No thanks!"); Log.Ln;
   END FeedMilk;
   
   (* Фабрика объетов *)
   PROCEDURE (d: Directory) New (type: INTEGER): Animal, NEW;
   VAR a: Animal; cat: Cat; dog: Dog;
   BEGIN
      CASE type OF 1:
         NEW(cat);
         a := cat;
      | 2 :
         NEW(dog);
         a := dog;
      ELSE END;
      dir.Add(a);
      
      RETURN a
   END New;
   
   PROCEDURE Test*;
      VAR a: Animal;
   BEGIN
      dir.root := NIL;
      (* add animals *)
      a := dir.New(1);
      a := dir.New(2);
      
      a := dir.root;
      WHILE a # NIL DO
         a.FeedMilk;
         a := a.next
      END
   END Test;

BEGIN
   NEW(dir);
   
END MyTest.

MyTest.Test


Вложения:
Test.odc [2.41 КБ]
Скачиваний: 84
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Пятница, 02 Сентябрь, 2016 20:48 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9099
Откуда: Россия, Орёл
VAR-аргумент указательного типа должен в точности соответствовать типу формального параметра.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Суббота, 03 Сентябрь, 2016 10:17 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1104
Откуда: СССР v2.0 rc 1
У меня мысль пришла, что можно попробовать сделать через CASE type_ OF.
Но, это не очень элегантно, имхо. При добавлении нового типа, поверх базового типа придётся циферки придумывать.
В Компонентном Паскале есть прямая проверка типа, так что в процедуру (теоретически) достаточно передавать просто базовый класс.
И посетила меня ещё одна мысль: а незачем мне все типы определять как указатели. Ведь мне важен только верхний уровень. только он и должен быть указателем. При присвоении NIL всё остальное сборщик мусора подгребёт по полной программе))

Короче, спасибо всем за подсказки, буду пробовать)
Я правильно понимаю, что фактически, в своём примере я предлагаю реализацию фабрики классов?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Суббота, 03 Сентябрь, 2016 12:28 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9099
Откуда: Россия, Орёл
Вы фабрики используйте, фабрики!


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Суббота, 03 Сентябрь, 2016 16:39 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2257
prospero78 писал(а):
Я правильно понимаю, что фактически, в своём примере я предлагаю реализацию фабрики классов?

Нет, у тебя не фабрика. Фабрику смотри в моем примере Directory.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Суббота, 03 Сентябрь, 2016 18:08 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1104
Откуда: СССР v2.0 rc 1
Я понял отличие. Принимает что угодно, а на выходе объект.
Не, у меня задача попроще. Количество объектов известно заранее. И их нужно уничтожать по окончанию дорасчёта. А уничтожить можно только через NIL в указатели. Тогда модули будут выгружаться как положено.
Поэтому, мне указатель нужен только на самом верху. Вниз с ними работать смысла не имеет.

Или мне для выгрузки модулей, это не поможет?)))


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Суббота, 03 Сентябрь, 2016 18:18 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2257
prospero78 писал(а):
Я понял отличие. Принимает что угодно, а на выходе объект.
Не, у меня задача попроще. Количество объектов известно заранее. И их нужно уничтожать по окончанию дорасчёта. А уничтожить можно только через NIL в указатели. Тогда модули будут выгружаться как положено.
Поэтому, мне указатель нужен только на самом верху. Вниз с ними работать смысла не имеет.

Или мне для выгрузки модулей, это не поможет?)))

Никогда в ручную не приходилось присваивать куда-то NIL. КП сам видит, когда объекты больше не нужны. Если объект больше не используется, например, он удален из списка, то на него нигде нет ссылок и его сборщик сам удалит.

Задача главная это выгружать модули?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Суббота, 03 Сентябрь, 2016 19:01 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1104
Откуда: СССР v2.0 rc 1
Да, именно так, Вань. Но у меня модули не выгружаются сами. В том-то и фишка. Вот думаю, может, через указатели сейчас сделаю, что-то изменится)) Через NIL то уже явно ресурсы освобождаться будут)).
Ну и с точки зрения надёжности, мне не помешает указатели в добровольно-принудительном порядке в NIL приводить.
Вообще, у меня задумка есть вообще все объекты типа в конфиг собрать в одном месте)) Тогда все модули будут выгружаться, кроме этого конфига)

Выгрузка нужна чтобы была возможность подредактировать модуль, скомпилять и снова в бой. А так приходится всю среду перезапускать. И я так подозреваю, что это не правильно от слова "совсем".


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Суббота, 03 Сентябрь, 2016 19:25 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2257
Модуль не выгружается не из-за объектов. А из-за того, что ты где-то его импортировал. Тут жесткое правило, что модули выгружаются только если нет других модулей, где он импортирован. Так что тебе нельзя этот модуль использовать в секции импорта нигде, только так.

Это на самом деле не очень сложно, вот тут есть пара примеров
http://gitlab.molpit.org/bindings/sdl2

Модуль Sdl2StdWin во время "ручного" импорта в примерах Obx* устанавливает себя как реализацию абстрактного интерфейса.

Код:
      (* Load realisations for current platform *)
      IF Dialog.IsWindows() THEN
         ASSERT(Kernel.ThisMod('Sdl2StdWin') # NIL, 20)
      ELSIF Dialog.IsLinux() THEN
         ASSERT(Kernel.ThisMod('Sdl2StdLin') # NIL, 20)
      ELSE HALT(20) END;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Суббота, 03 Сентябрь, 2016 19:42 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1104
Откуда: СССР v2.0 rc 1
Это понятно, что если один модуль импортирует другой, то, тот который уровнем глубже не может быть выгружен. Тут фишка получается, что какой-то модуль из верхнего уровня продолжает в памяти висеть, даже после закрытия окна. Так вот непонятно, почему такой модуль остаётся в памяти, если его ничего не держит, и соответственно, все остальные модули уровнями ниже?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Суббота, 03 Сентябрь, 2016 19:55 
Аватара пользователя

Зарегистрирован: Четверг, 08 Октябрь, 2009 15:00
Сообщения: 2257
prospero78 писал(а):
Это понятно, что если один модуль импортирует другой, то, тот который уровнем глубже не может быть выгружен. Тут фишка получается, что какой-то модуль из верхнего уровня продолжает в памяти висеть, даже после закрытия окна. Так вот непонятно, почему такой модуль остаётся в памяти, если его ничего не держит, и соответственно, все остальные модули уровнями ниже?

А модули сами, как я понял, вообще не выгружаются... Я думал по началу, что было бы логично, если бы они сами выгружались, но не тут то было.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Суббота, 03 Сентябрь, 2016 22:21 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1104
Откуда: СССР v2.0 rc 1
Но раз подсчёт модулей ведётся, и ссылки на них, всё-таки должна быть команды выгрузки? Ведь БлэкБокс как-то их сам выгружает??
Впрочем.... Что мне мешает открыть команду меню?))))


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: NEW в процедуре.
СообщениеДобавлено: Суббота, 03 Сентябрь, 2016 23:09 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1104
Откуда: СССР v2.0 rc 1
Не побоялся залезть в Kernel, и оказалась задача с принудительной выгрузкой модулей вполне решаема!
Вот что я родил:
Код:
PROCEDURE Модуль_выгрузить(IN мод_: ARRAY OF CHAR);
   VAR
      модуль: мЯдро.Module;
   BEGIN
      модуль:=мЯдро.ThisMod(мод_);
      мЯдро.UnloadMod(модуль)
   END Модуль_выгрузить;

где, мЯдро := Kernel.

Не знаю, на сколько это безопасно, на зато проверено на 4-х модулях -- работает!!!)))


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 30 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа


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

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


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

Найти:
cron
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2019, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB