|
|
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
Добрый день всем! Обнаружил, с неприятными для себя последствиями, что классовые конструкторы дженерик-классов вызываются каждый раз при динамической загрузке пакетов bpl ... Вызываются именно через инициализацию пакетов (LoadPackage). Для обычных классов классовые конструкторы/деструкторы вызываются один раз, сколько раз не загружай/выгружай дополнительные пакеты. Например, классовый конструктор приведенного ниже дженерик-класса будет вызван каждый раз , когда будем динамически грузить bpl. Код: pascal 1. 2. 3. 4. 5. 6. А для вот такого класса все как обычно, - классовые конструктор/деструктор будут вызваны только один раз , при загрузке пакета в котором класс расположен. Код: pascal 1. 2. 3. 4. 5. 6. Подскажите, кто сталкивался. Можно ли добиться от дженерик-классов стандартного поведения? Если нет, то с чем это связано? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2020, 22:07 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
Virtual Student, Может конструктор дженерика вызывается для разных T? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2020, 22:58 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
По идее если пакет Foo использует дженерик<Integer> и пакет Bar использует дженерик<Integer> - он должен сконструироваться дважды. Дело в том, что обычный класс известный и его код попадает в пакет, где он объявлен. А вот дженерики могут быть преобразованы в бесконечное число типов. И они уже кладутся в тот пакет, где объявлены. Если принципиально, что какая-то информация была уникальная для всех дженерик одного T - нужно на стороне главного модуля сделать синглетон от TypeInfo(T) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2020, 23:05 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
SOFT FOR YOU Virtual Student, Может конструктор дженерика вызывается для разных T? Для разных T, закономерно вызывается при загрузке основного пакета приложения. А потом, при каждой динамической загрузке/выгрузке пакетов, каждый раз дергает конструкторы/деструкторы всех дженерик-классов упоминаемых в загружаемом пакете . :( Получается как бы, что для каждого динамического пакета инициализируется свой набор дженерик-классов... Пробовал организовать RegisterClass не получается, т.к. жденерик-классы не унаследованы от TPresistent. Может есть другой путь? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2020, 23:07 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
SOFT FOR YOU Если принципиально, что какая-то информация была уникальная для всех дженерик одного T - нужно на стороне главного модуля сделать синглетон от TypeInfo(T) Можно поподробнее или где-то почитать!? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2020, 23:12 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
Можно вообще сделать с подсчётом ссылок :) var D: TDictionary<PTypeInfo,Integer>; procedure Register(I: PTypeInfo); begin if D.TryGetValue(I, Count) then D[I] := Count + 1 else begin D.Add(I, 1); InternalConstruct(I); end; Ну что-то типа такого. И Unregister по аналогии. С мобилы просто пишу ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2020, 23:25 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
SOFT FOR YOU, Это не совсем то, чего мне нужно добиться... При объявлений дженерика, генерируется новый класс. Я пытаюсь использовать это для общих полей, так сказать Код: pascal 1. чтобы каждый унаследованный класс-дженерик имел свой набор вложенных объектов . Подход работает, но только в рамках главного пакета приложения. А динамическая загрузка/выгрузка доп. пакетов все портит на корю... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.10.2020, 23:47 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
A class constructor is a special class method that is not accessible to developers. Calls to class constructors are inserted automatically by the compiler into the initialization section of the unit where the class is defined Вызов классового конструктора автоматически помещается в секцию initialization. При подключении пакета вызывается секция initialization. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2020, 00:26 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
Virtual Student, А ты хочешь чтобы при компиляции главного пакета в него попадали классы, о которых он не знает? ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2020, 00:28 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
SOFT FOR YOU Virtual Student, А ты хочешь чтобы при компиляции главного пакета в него попадали классы, о которых он не знает? ) Нет. Я хочу, чтобы дженерик-классы не проходили заново инициализацию при динамической загрузке пакетов. По тому, что их классовые переменные можно использовать вместо глобальных объектов. Например прописать в классовые переменные каталоги, справочники, нулевые элементы и т.п... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2020, 09:57 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
Например прописать в классовые переменные каталоги, справочники интересно, о чем тут идет речь ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2020, 10:42 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
Virtual Student, Я тоже сталкивался с этим. Особенность Delphi в том, что сколько у вас будет производных классов от дженериков - столько по сути разных базовых классов будет, и для каждого будет вызываться классовые конструкторы и деструкторы. Особенность Delphi в том, что в чистом виде дженериков нет, компилятор их преобразует во время компиляции в производные классы. т.е. в RTTI вы не увидите TIdComplex<> и не сможете построить дженерик или выделить подкласс, как это сделано в .Net Вместо этого вы увидите TIdComplex<A> TIdComplex<B> TIdComplex<C> а это по сути 3 класса. Эту проблему можно решить через синглтон ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2020, 12:44 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
Virtual Student, Ну так я же сказал, как это сделать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2020, 13:39 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
X-Cite Virtual Student, Вместо этого вы увидите TIdComplex<A> TIdComplex<B> TIdComplex<C> а это по сути 3 класса . Это меня как раз и устраивает! И этим пользуюсь создавая по сути в каждом классе свои, общие для конкретного дженерик-класса , необходимые мне структуры (например, каталог единиц измерения для мат. расчетов в самом классе единицы измерения TUnit). Моя проблема в том, что в динамически загружаемых пакетах, я вижу вместо этих структур - nil ... Внутри основного пакета (ядра) все прекрасно работает, а также для некоторых случаев загрузки ссылки сохраняются (это чистая случайность). Реализовал костыль с глобальным управлением этими ресурсами. Но мне не нравиться, что для поиска по каталогу, мне нужно перед этим искать сам каталог по соответствию нужному классу в словаре... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2020, 16:10 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
L_argo Например прописать в классовые переменные каталоги, справочники Каталоги, данные которых постоянно нужны в формах и отчетах. Например справочник "единицы измерения", содержащий коды красивой (с индексами пр...) отрисовки единиц измерения в таблицах, деревьях и отчетах. Или виды операций со значками и самими операторами. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2020, 16:14 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
Virtual Student, Если в динамических пакетах эти классы только описаны - нет экземпляров классов, то классовые конструкторы и деструкторы не будут вызваны. Если вы создаете экземпляры через RTTI, не используя напрямую, токлассовые конструкторы и деструкторы тоже не будут вызваны. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2020, 16:16 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
X-Cite Virtual Student, Если в динамических пакетах эти классы только описаны - нет экземпляров классов, то классовые конструкторы и деструкторы не будут вызваны. В динамических пакетах эти классы только используются... Никаких новых экземпляров таких классов не создается. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2020, 16:25 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
А что, bpl-и прям в рантайме постоянно грузятся-выгружаются? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2020, 17:02 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
Логично, что если вы выгрузили пакет, то при выгрузке вызывается финализация всего, что было в пакете в т.ч. и глобальные переменные, коими и являются классовые переменные... Когда вы загружаете пакет, то они соответственно инициализируются... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2020, 17:13 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
X-Cite Логично, что если вы выгрузили пакет, то при выгрузке вызывается финализация всего, что было в пакете в т.ч. и глобальные переменные, коими и являются классовые переменные... Когда вы загружаете пакет, то они соответственно инициализируются... Я ж говорю, - гранаты не той системы. :) exe <-> kernel.bpl ( здесь лежат дленерик-классы , да и вообще вся бизнес-логика приложения) <-> form1.bpl <-> form2.bpl ... <-> formN.bpl kernel.bpl грузиться вместе с exe . При разных пользовательских действиях из БД (online/onklick система обновления) подгружаются нужные редакторы (пакеты), админки, логилки и т.п. из пакетов formN.bpl Формы из пакетов formN.bpl работают с данными и структурами, загружаемыми в kernel.bpl . Загружая/выгружая пакет формы formN.bpl я не ожидаю, что мои дженерик-классы будут инициализироваться/финализироваться заново. При этом, обычные классы инициализируются/финализируются штатно , т.е. при загрузке/выгрузке пакета ядра kernel.bpl , а не в коем случае при загрузке/выгрузке динамических пакетов... Вот что я пытаюсь разрулить... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2020, 17:58 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
К стати, пробовал грузить blp-ки без инициализации (LoadLibrary). Инициализация не происходит, но ссылки бьются... :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2020, 18:00 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
Virtual Student kernel.bpl ( здесь лежат дленерик-классы , да и вообще вся бизнес-логика приложения) Если под этим имеется ввиду, что тут описаны классы: Код: pascal 1. 2. 3. Virtual Student Формы из пакетов formN.bpl работают с данными и структурами, загружаемыми в kernel.bpl . А тут они используются: Код: pascal 1. То описываемое поведение корректно т.к. дженерик обретает "физическую форму" в момент конкретизации/специализации. Что с этим делать. В основном пакете подготовить все необходимые типы: Код: pascal 1. 2. 3. 4. В дочерних пакетах использовать только этот набор. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2020, 18:07 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
[quot Kazantsev Alexey#22221616] Virtual Student Что с этим делать. В основном пакете подготовить все необходимые типы: Код: pascal 1. 2. 3. 4. В дочерних пакетах использовать только этот набор. Да. Так оно везде и сделано! Эффект сохраняется... Но инициализируются не TMyClassWithByte и TMyClassWithString, а TMyClass<Byte> и TMyClass<String>. Наследование дженериков у нас организовано значительно сложнее... Например: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. В нашем случае повторно инициализируются классы типа TComplexObject<TOrg> и т.п... Есть подозрения, что все проблемы от конструкции наследования самого от себя, как сделан TOrg... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2020, 18:33 |
|
||
|
Классовые конструкторы/деструкторы дженериков...
|
|||
|---|---|---|---|
|
#18+
Virtual Student, И зачем было делать так сложно? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.10.2020, 18:35 |
|
||
|
|

start [/forum/topic.php?fid=58&msg=40012273&tid=2037902]: |
0ms |
get settings: |
9ms |
get forum list: |
18ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
156ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
45ms |
get tp. blocked users: |
1ms |
| others: | 241ms |
| total: | 486ms |

| 0 / 0 |
