Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 11.08.2010, 14:14   #11
Greek9000
Форумчанин
 
Регистрация: 01.09.2009
Сообщений: 151
По умолчанию

Цитата:
Сообщение от GunSmoker Посмотреть сообщение
Пакет - это обычная DLL. Соответственно и грузится он согласно правилам загрузки DLL.
GunSmoker, вы проявили завидную осведомлённость в вопросах динамического подключения DLL-ек. Может намекнёте (ссылкой или словами) каким образом обычная dll (т.е. - пакет) имеет единое адресное пространство с приложением?
Greek9000 вне форума Ответить с цитированием
Старый 11.08.2010, 14:45   #12
Ins
Форумчанин
 
Регистрация: 29.12.2007
Сообщений: 137
По умолчанию

Я не GunSmoker, но адресное пространство имеет процесс, библиотека собственный процесс не создает, это просто код, который может быть загружен в адресное пространство процесса, которому он понадобится
Ins вне форума Ответить с цитированием
Старый 12.08.2010, 02:46   #13
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Дополняя ответ Ins-а - обычно в таких случаях советуют почитать Рихтера.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 12.08.2010, 03:13   #14
r9m
₪₪₪₪₪₪₪₪
Форумчанин
 
Аватар для r9m
 
Регистрация: 16.04.2007
Сообщений: 471
По умолчанию

Дополняя GunSmoker - нужно читать вообще.
r9m вне форума Ответить с цитированием
Старый 12.08.2010, 12:13   #15
Greek9000
Форумчанин
 
Регистрация: 01.09.2009
Сообщений: 151
По умолчанию

Цитата:
Сообщение от Ins Посмотреть сообщение
Я не GunSmoker, но адресное пространство имеет процесс, библиотека собственный процесс не создает, это просто код, который может быть загружен в адресное пространство процесса, которому он понадобится
Вы, уважаемый, цепляетесь к словам. Понятно же, когда говорят "у меня в exe-шнике выполняется процедура ..." имеется ввиду, что эта процедура выполняется совсем не в нутри файла, хранящегося на диске Поэтому задам вопрос по другому:
- почему, когда я загружаю dll (в которой есть вызов RegisterClass(TMyClass)) методом LoadLibrary, то вызов в главной форме GetClass(TMyClass) возвращает nil, а когда грузится пакет методом LoadPackage, то тот же самый вызов возвращает ссылку на зарегистрированный класс?
Другими словами, почему в первом случае таблица RTTI, Application и Screen различаются, а во втором случае они общие для dll и приложения?

Я даже больше скажу:
LoadPackage грузит пакет методом LoadLibrary (естественно с проверками), после чего ищет функцию Initialize в этом пакете и вызывает её. Поэтому вопрос может звучать так: "Что делает ф-ция Initialize, которая автоматически вставляется в любой bpl-пакет?".

P.S. Рихтера скачал - читаю. Полезная книжка.

Последний раз редактировалось Greek9000; 12.08.2010 в 12:19.
Greek9000 вне форума Ответить с цитированием
Старый 12.08.2010, 12:45   #16
Ins
Форумчанин
 
Регистрация: 29.12.2007
Сообщений: 137
По умолчанию

Цитата:
Вы, уважаемый, цепляетесь к словам.
Чего??? )) Я, вообще-то, ответил на вопрос, который ты задал. Если тебя интересовал другой вопрос, то нужно было его и задать. Телепатические способности, увы, утратил при рождении

Отвечая на твой ДРУГОЙ вопрос - дело в том, что при компиляции обычной DLL, все юниты, которые она использует, включаются в ее состав, таким образом, у exe и каждой из dll-ок внутри своя версия юнита System, Classes и т.д. Т.е. каждый исполняемый модуль (exe, dll) имеет не только собственную версию кода юнитов, но и собственные RTTI, списки классов, менеджер памяти и прочие структуры данных. Когда мы компилируем с пакетами, юниты, их код и структуры данных, присутствуют только в одном экземпляре внутри своего пакета. Поэтому инфа общая и доступ к ней централизованный. Переводя это на пример с RegisterClasses/GetClass...
Случай с обычной DLL
1. RegisterClasses в DLL вызывает код из юнита Clases, включенного в состав этой DLL и заносит данные в собственный список классов
2. GetClass в EXE вызывает код из юнита Classes, включенного в состав этого EXE. Так как список классов EXE-шника ничего не знает о списке классов DLL, то для EXE этот класс не зарегистрирован
Случай с пакетами
1. Вызов RegisterClasses произвольного пакета обращается к функции из пакета rtl.bpl и заносит класс в список этого пакета
2. Вызов GetClass из произвольного пакета или приложения, использующего пакеты, обращается к функции из того же пакета rtl.bpl, которая, как видно выше, знает о том, что класс был зарегистрирован

Вот и вся магия. Это же, кстати, еще и причина того, что
1. Операторы is/as не будут работать в exe, если объект создан в dll и наоборот (если использовать пакеты - будут работать). Видел когда-нибудь ошибку с текстом "Can not assign TFont to TFont"? Вот это она и есть. DLL.TFont <> EXE.TFont
2. Нельзя гонять между dll и exe объекты и классы, т.к. кроме п.1. можно нарваться на множество проблем, связанных с несоответствием данных класса или объекта в приложении и библиотеке (опять таки, в случае использования пакетов - можно)
3. Нельзя так просто выделить память в exe а освободить в dll и наоборот - нужно расшаривать менеджер памяти (ShareMem, SimpleShareMem), так как менеджер не может освободить память, которую он не выделял, в его записях нет необходимых для этого данных. При использовании пакетов такой проблемы нет, менеджер памяти и так единый

Последний раз редактировалось Ins; 12.08.2010 в 13:34.
Ins вне форума Ответить с цитированием
Старый 12.08.2010, 14:16   #17
Greek9000
Форумчанин
 
Регистрация: 01.09.2009
Сообщений: 151
По умолчанию

Цитата:
Сообщение от Ins Посмотреть сообщение
Чего??? )) Я, вообще-то, ответил на вопрос, который ты задал. Если тебя интересовал другой вопрос, то нужно было его и задать. Телепатические способности, увы, утратил при рождении
Признаю, что был не прав, задав вопрос системным программистам с позиций прикладного программиста (тока сильно не пинайте! сами мы не местные, ассемблеров не знаем, смещениев не изучали )

Итак, возвращаясб к напечатанному...

Получается, что есть принципиальная возможность зарегистрировать класс формы в dll-ке и передать его в приложение? (Тут речь не идёт о том, как это сделать - только о возможности этого)
После редактирования предыдущего поста вопрос снят, как и следующий, вытекающий из первого
Думается мне, что не все телепатические способности были утрачены при рождении


Если этот так, то сразу возникает след. вопрос.

Предположим, что подобный вызов
dll_frmClass = MyGetDLLClass('TfrmDLL');
вернёт мне ссылку на класс формы хранящейся в DLL (скомпилированный. без пакетов). Тогда смогу ли я работать с dll_frmClass так же, как если бы я получил на него ссылку при помощи стандартной GetClass?
Тоесть, можно ли будет выполнить примерно такой код
Код:
frm := dll_frmClass.Create(nil); // Создаём экземпляр формы
frm.BorderStyle := bsNone; // Границы и системные кнопки ни к чему
frm.Align := alClient; // 
frm.Parent := frmMain.pnlContainer; // Размещаем форму на панели
без передачи экземпляра Application в dll-ку и других шаманских выкрутасов, сопровождающих размещение форм в dll-ках?

Последний раз редактировалось Greek9000; 12.08.2010 в 14:33.
Greek9000 вне форума Ответить с цитированием
Старый 12.08.2010, 14:20   #18
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Цитата:
LoadPackage грузит пакет методом LoadLibrary (естественно с проверками), после чего ищет функцию Initialize в этом пакете и вызывает её. Поэтому вопрос может звучать так: "Что делает ф-ция Initialize, которая автоматически вставляется в любой bpl-пакет?".
Функция Initialize делает работу, которая в DLL сидит в DllMain: вызов секций initialization модулей.

Цитата:
Предположим, что подобный вызов
dll_frmClass = MyGetDLLClass('TfrmDLL');
вернёт мне ссылку на класс формы хранящейся в DLL (скомпилированный. без пакетов). Тогда смогу ли я работать с dll_frmClass так же, как если бы я получил на него ссылку при помощи стандартной GetClass?
Да, но только при условии, что и DLL и exe собраны в одной версии компилятора (для пакетов это условие выполняется автоматически).

Поскольку этим вы привязываетесь к Delphi, то зачем вам DLL? Почему бы просто не использовать пакеты - ведь это удобно.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.

Последний раз редактировалось Stilet; 12.08.2010 в 14:25.
GunSmoker вне форума Ответить с цитированием
Старый 12.08.2010, 14:24   #19
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Тогда смогу ли я работать с dll_frmClass так же, как если бы я получил на него ссылку при помощи стандартной GetClass?
А чего нет? Вполне сможешь если ссылка вернется правильная.
Проверь ее на nil и на TfrmDLL и если все верно работай.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 12.08.2010, 14:26   #20
Ins
Форумчанин
 
Регистрация: 29.12.2007
Сообщений: 137
По умолчанию

Цитата:
Тогда смогу ли я работать с dll_frmClass так же, как если бы я получил на него ссылку при помощи стандартной GetClass?
Может показаться что сможешь, но на самом деле - считай что нет (читай предыдущее сообщение п.2). На самом деле это будет работать только в случае ПОЛНОЙ ИДЕНТИЧНОСТИ кода класса в exe и dll, а ее очень просто нарушить, например, если твоя dll скомпилирована в другой версии delphi или с другой версией rtl или с другой версией твоих классов. НЕЛЬЗЯ гонять объекты между dll и exe, запомни как правило, даже если тебе кажется, что ты сможешь это сделать и все будет нормально. Мы однажды поступили так и сильно пожалели - пришлось в уже готовом приложении пересматривать архитектуру, прицепляя к классам интерфейсы. В общем, для обмена объектами между dll или exe нужно либо использовать пакеты, либо посмотреть в сторону COM (в простейшем случае именно COM-сервер реализовывать не обязательно, но принцип должен быть тем же - экспорт интерфейсов и только com-безопасные типы в параметрах методов)

Цитата:
Проверь ее на nil и на TfrmDLL и если все верно работай.
Это как, is-ом, что-ли?

Цитата:
После редактирования предыдущего поста вопрос снят, как и следующий, вытекающий из первого
Думается мне, что не все телепатические способности были утрачены при рождении
Ну вот, зря пост писал...

Последний раз редактировалось Ins; 12.08.2010 в 14:36.
Ins вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Runtime runtime = Runtime.getRuntime(); Pti44ka Общие вопросы по Java, Java SE, Kotlin 1 22.11.2009 10:45
без запроса Package? koleko Общие вопросы Delphi 2 18.02.2009 22:59
RunTime Error713 (VB) vio Помощь студентам 2 12.12.2008 20:45
Unit 'MyLib' implicitly imported into package 'MyPackage'. как исправить? SkAndrew Компоненты Delphi 0 06.04.2008 00:28
Runtime programming JoanM Общие вопросы Delphi 4 09.01.2008 11:00