Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Проблемма с переменными в DLL 
V
    Опции темы
Dronishe
  Дата 6.1.2007, 22:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 7.11.2006

Репутация: нет
Всего: нет



Имеются: программа и 2 dll.

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

Суть проблемы:

Вторая длл получает переменную, но изменение её в этой длл, не изменяет её в первой длл. smile 

Как мне изменить переменную из первой длл через вторую длл, так что бы изменения коснулись обеих длл? 

smile 
PM MAIL   Вверх
Romikgy
Дата 6.1.2007, 23:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 26
Всего: 146



указатель на эту переменную передай и изменяй че и где хошь!
А вообще имхо 
Цитата(Dronishe @  6.1.2007,  21:22 Найти цитируемый пост)
длл

плохо работает с 
Цитата(Dronishe @  6.1.2007,  21:22 Найти цитируемый пост)
класса

и надо быть очень аккуратным


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Dronishe
Дата 6.1.2007, 23:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 7.11.2006

Репутация: нет
Всего: нет



Я попробую ещё раз...

У меня есть 2 DLL. В первой - созданн объект какогонибудь класса. Во второй есть процедура, которая должна на этот объект повлиять.

Вторая длл получает переменную, но изменение её в этой длл, не изменяет её в первой длл.

Как мне изменить переменную из первой длл через вторую длл, так что бы изменения коснулись обеих длл?

Потому что первая длл - скриптовый движок, а вторая - всего лишь набор дополнительных ф-ий, которые должны без труда подключатся к первой длл

ф-ии в скриптовом движке создаются через отдельные классы

Для того что бы добавить в движок новую функцию - надо создавать отдельный класс.

Я предполагал, что движок будет лежать в одной длл, а все фуии будут описанны в другой

А для того что бы Фи-я добавилась в движок, надо сделать ей create с некторыми параметрами, один из которых - Объект-список уже имеющихся фу-ий. Этот Объект-список есть в первой длл

а он нужен во второй. При этом надо чтобы при изменении во второй он изменился и в первой.

вот собственно в чем байда....

Я точно убью себя ап стену....  smile 

PM MAIL   Вверх
former
Дата 7.1.2007, 01:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


MEMS Expert
***


Профиль
Группа: Завсегдатай
Сообщений: 1166
Регистрация: 1.3.2006
Где: Россия

Репутация: 5
Всего: 17



Здесь что-то было по совместное использование DLL: http://www.podgoretsky.com/ftp/Docs/Delphi...ogLib/ch_02.htm


--------------------
Достаточно снизить уровень мышления, чтобы иные почувствовали почву под ногами.
PM MAIL   Вверх
Alexeis
Дата 7.1.2007, 14:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Адресное пространство Длл отображается в адресное пространство программы, но к сожалению Длл не может напрямую использовать объекты программы и программа не может использовать объекты соданные в длл. И длл не может использовать объекты созданные в другой длл. Если сильно надо, то такой механизм можно реализовать через интерфесы (например так как это сделано при использовании GDI+). Использование напрямую приведет к неопределенным последствиям.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Romikgy
Дата 7.1.2007, 16:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 26
Всего: 146



Dronishe, приведи код , и приложения и двух dll вот и посмотрим что к чему
PS не в обиду те , но и объясняешь , что те надо ты с трудом, да и с первого раза не понимаешь , что те говорят!


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
MetalFan
Дата 7.1.2007, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



Цитата(Alexeis @  7.1.2007,  14:47 Найти цитируемый пост)
Совершенно верно! Адресное пространство Длл отображается в адресное пространство программы, но к сожалению Длл не может напрямую использовать объекты программы и программа не может использовать объекты соданные в длл. И длл не может использовать объекты созданные в другой длл. Если сильно надо, то такой механизм можно реализовать через интерфесы (например так как это сделано при использовании GDI+). Использование напрямую приведет к неопределенным последствиям. 


нет такого понятия "Адресное пространство Длл". есть АП ПРОЦЕССА! а в него и "отражаются"/загружаются ВСЕ используемые в программе DLL. ведь что такое DLL? - это по сути просто кусок кода/данных, который физически находится на диске в другом файле... все.
а объекты/классы - это уже нагрузка ООП, и Делфи в частности.
читать много раз до полного просвещения: Глава 19. DLL основы


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Alexeis
Дата 7.1.2007, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Цитата(MetalFan @  7.1.2007,  18:06 Найти цитируемый пост)
нет такого понятия "Адресное пространство Длл". есть АП ПРОЦЕССА!

  Ух какой же ты вредный. Прям так и нет. Не увидел в умной книжке, значит все чего там нет неправда.
Dll это данные, которые не загружаются непосредственно в память процесса. Загружаются сначала в некое  промежуточное адресное пространство не принадлежащее процессу. А только затем оно отображается в память процесса. Что неправильного в том что я назвал его адресным пространством Dll? Ведь она находится в нем, а значит это ее адресное пространство. Если одну и ту же библиотеку загрузили 2е программы, то это адресное пространство отображается на 2 процесса. Оно действительно независимое с точки зрения ОС. Программа получает только проекцию. Таким образом при помощи того же хука получаем доступ к адресному пространству другого процесса. Если бы Dll принадлежала только адресному пространству процесса, то хрен бы другой процесс мог бы вытащить из нее данные. А так может. А может потому что Dll расположена в некоторой своей области. Если мы завершим процесс, то его адресное пространство уничтожится, в этом случае и Dll должна быть выгружена, но этого не происходит, потому что она находится в своем адресном пространстве и используется другими процессами.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
MetalFan
Дата 7.1.2007, 19:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



Alexeis, а Вы где увидели? в другой умной книжке? сами нашли?
ну я не спорю, что ДЛЛ до отображения в АП процесса где-то в памяти уже висит, но это нас никак не касается, "достучаться" до той памяти мы не можем(стандартными средствами), и при работе с DLL после явной(динамической)/неявной(статической) загрузки ее в АП процесса нет для библиотеки понятия своего АП.
а хуки - это отдельный разговор, т.к. там загрузкой библиотеки в чужое АП рулит сама система.


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Dronishe
Дата 7.1.2007, 20:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 7.11.2006

Репутация: нет
Всего: нет



Спасибо за внимание. Уже разобрался. Перенес всю работу с этой переменной в первую длл. Пришлось делать все через ";jge"  зато работает
PM MAIL   Вверх
Alexeis
Дата 7.1.2007, 21:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



MetalFan, тем не менее. Простота работы с dll лишь кажущаяся. То что нам доступны ее функции еще не означает, что код в dll является таким же кодом как и код в нашей программе. Совсем нет. Dll следует рассматривать скорее как сервер, а программу как клиент. Dll по своей сути это полноценная программа (не имеющая правда единой точки входа), со всеми вытекающими последствиями. Загрузка dll сходна скорее с мапингом области памяти чужого процесса. Представьте себе, что мы запустили чужую программу, остановили ее основной поток, спроецировали ее адресное пространство в нашу программу (memory maping) объявив его исполняемым и нашли точки входа всех ее функций, после чего вызываем их. 
  Вот с dll аналогично. Это совсем чужой модуль, который функционирует по своему, при этом он может обращаться ко своим внутренним переменным, объектам, объектам ядра, о которых мы понятия не имеем. Созданы ли они или нет, как созданы, как организованы внутренние связи? Все это нам не доступно. Dll для программы это некий черный ящик к доступ к которому строго регламентирован (потому и провел аналогию с сервером). Многие вольности и извороты, возможные в без проблем программе (ведь тут мы все контролируем!) недоступны там. Вообще какова бы ни была библиотека (динамически ли загруженная либо она загружается при загрузке программы автоматом, либо она относится к ядру ОС или это хук) используются общие механизмы работы с ней. Кажущаяся простота работы обманчива. Управление dll производится ОС, потому очень многое скрыто от глаз программиста, потому во избежании непонятных ошибок следует в точности соблюдать все правила работы с ней и не использовать ничего из того, что не задокументировано. 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Alexeis
Дата 7.1.2007, 21:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



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


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
MetalFan
Дата 7.1.2007, 22:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



Цитата(Alexeis @  7.1.2007,  21:09 Найти цитируемый пост)
То что нам доступны ее функции еще не означает, что код в dll является таким же кодом как и код в нашей программе. Совсем нет.

почему же? обоснуйте. после отражения в память процесса таковым и является.

вот что пишет по этому поводу Рихтер. с ним то вы спорить не будете? или он в корне не прав? 
но Вы пока никак не доказали обратное.
Цитата
Как только DLL спроецирована на адресное пространство вызывающего процесса, ее функции доступны всем потокам этого процесса Фактически библиотеки при этом теряют почти всю индивидуальность: для потоков код и данные DLL — просто дополнительные код и данные, оказавшиеся в адресном пространстве процесса. Когда поток вызывает из DLL какую-то функцию, та считывает свои параметры из стека потока и размещает в этом стеке собственные локальные переменные Кроме того, любые созданные кодом DLL объекты принадлежат вызывающему потоку или процессу — DLL ничем не владеет.


Цитата(Alexeis @  7.1.2007,  21:09 Найти цитируемый пост)
Это совсем чужой модуль, который функционирует по своему, при этом он может обращаться ко своим внутренним переменным, объектам, объектам ядра, о которых мы понятия не имеем. Созданы ли они или нет, как созданы, как организованы внутренние связи? Все это нам не доступно. Dll для программы это некий черный ящик к доступ к которому строго регламентирован

каким таким "своим"? они все открытые объекты ядра будут относиться к процессу, куда загружена/отображена DLL, а не к самой длл. иначе как система освобоболит ресурсы при "убитии" процесса?
ну если в локальной процедуре в программе тоже обращаться к объектам ядра, это же не значит, что она имеет свое АП?

Romikgy, а если не "хе-хе"? просветите уж плиз)




--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Romikgy
Дата 7.1.2007, 23:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 26
Всего: 146



Цитата(MetalFan @  7.1.2007,  21:12 Найти цитируемый пост)
Когда поток вызывает из DLL какую-то функцию, та считывает свои параметры из стека потока и размещает в этом стеке собственные локальные переменные 

Согласен , но что ты скажешь о глобальных переменных объявленных в dll ?
Цитата(MetalFan @  7.1.2007,  21:12 Найти цитируемый пост)
Кроме того, любые созданные кодом DLL объекты принадлежат вызывающему потоку или процессу — DLL ничем не владеет.

выше,
плюс т.к. дллки могут писатся на разных языках, то омен между dll и приложением объектов имхо затруднен
допустим я написал приложение на С++ а dll на дельфи, и в dll создаю объект класса TStringList как мне его передать в программу?
вот поэтому и пытаются делать обмен между dll и приложением только стандартными типами , как char , byte, word, dword и т.п. 
Цитата(MetalFan @  7.1.2007,  21:12 Найти цитируемый пост)
а если не "хе-хе"?

а если без хехе, то доступ даже к  АП другого процесса вполне разрешен, не то что к АП dll 


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Alexeis
Дата 7.1.2007, 23:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Я против такого объяснения, потому что из-за таких вот объяснений люди часто наступают на вилы. Создается иллюзия того, что dll это просто кусок кода такой же как и любой другой в программе. На самом деле windows предоставляет доступ к функциям так как если бы они были реализованы в самой программе. Но только и всего. Кто сказал, что все что имеется в dll экспортируется из нее? Совсем нет. Экспортируется  только часть функций предназначенных для экспорта. У длл есть секция инициализации, которая выполняется при ее загрузке. Там могут создаваться свои внутренние объекты и переменные которые недоступны извне. 

Цитата(MetalFan @  7.1.2007,  22:12 Найти цитируемый пост)
для потоков код и данные DLL — просто дополнительные код и данные, оказавшиеся в адресном пространстве процесса.

  Так то оно так. Формально доступ к ним хоть и можно получить, но что с ними делать? Одно дело атомарные типы, а другое объекты классов. Поскольку сами классы экспортировать нельзя, то сама программа и не может с ними работать. Программа может работать с объектами своих классов (описанных в ней). 
Цитата(MetalFan @  7.1.2007,  22:12 Найти цитируемый пост)
Когда поток вызывает из DLL какую-то функцию, та считывает свои параметры из стека потока и размещает в этом стеке собственные локальные переменные

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

Цитата(MetalFan @  7.1.2007,  22:12 Найти цитируемый пост)
DLL ничем не владеет.
 Если ее адресное пространство полностью отображается в программу, то опять же можно считать, что всем владеет программа, но вот банальный пример, создали мы windows окно. Фактически программа получает только его дескриптор, а сам объект остается скрытым. Разве мы можем напрямую изменить состояние окна "EDIT"? Хотя формально он и создается в программе, но что толку от этого? Его структура нам неизвестна. На его состояние мы можем повлиять только посредством функций да и то если он захочет изменить состояние, а не захочет не изменит. Нам доступно только то, что хотели разрешить производители, тогда как изнутри с ним можно сделать намного больше. Потому я и утверждаю, что объектом владеет библиотека, потому что всегда мы просим ее что-то сделать, а не требуем. Если у меня радиоприемник, то я могу крутить его и вертеть по своему желанию, если радиоприемник есть у Васи, то я максимум могу попросить его настроить его на свою любимую радиостанцию, а Вася может с ним делать что угодно. В такой ситуации мы говорим, что радиоприемник  Васин, а не мой. 
  Во времена процедурного программирования, атомарных типов ситуация была похожа на то что описывается у Рихтера. А вот попробуйте скажем удалить объект GDI+. Нифига не выйдет! Максимум, что можно это освободить интерфейс. Аналогичная ситуация и с COM объектом. Мы его создали но не владеем в полной мере, хотя и имеем доступ к его памяти.

Добавлено @ 23:49 
Оговорюсь, имеем доступ, только если он реализован в dll.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
MetalFan
Дата 8.1.2007, 01:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



Цитата(Romikgy @  7.1.2007,  23:16 Найти цитируемый пост)
Цитата(MetalFan @  7.1.2007,  21:12 Найти цитируемый пост)
Когда поток вызывает из DLL какую-то функцию, та считывает свои параметры из стека потока и размещает в этом стеке собственные локальные переменные 
Согласен , но что ты скажешь о глобальных переменных объявленных в dll ?

а что о них говорить? кусок зарезервированного/занятого АП, доступный на чтение и на запись.

Цитата(Romikgy @  7.1.2007,  23:16 Найти цитируемый пост)
плюс т.к. дллки могут писатся на разных языках, то омен между dll и приложением объектов имхо затруднен
допустим я написал приложение на С++ а dll на дельфи, и в dll создаю объект класса TStringList как мне его передать в программу?
вот поэтому и пытаются делать обмен между dll и приложением только стандартными типами , как char , byte, word, dword и т.п. 


ну да, все ясно. но DLL попрежнему ничем не владеет) все созданные функциями DLL объекты/классы распологаются в АП процесса и являют для него просто кусками памяти с данными, разве не так?

Цитата(Romikgy @  7.1.2007,  23:16 Найти цитируемый пост)
Цитата(MetalFan @  7.1.2007,  21:12 Найти цитируемый пост)
а если не "хе-хе"?
а если без хехе, то доступ даже к  АП другого процесса вполне разрешен, не то что к АП dll 

ну и на здоровье. я в курсе, что один процесс может обращаться к ВАП другого процесса. но повторюсь, нет у DLL своего АП!!! а значит не к чему получать доступ.

так, теперь с другим оппонентом)


Цитата(Alexeis @  7.1.2007,  23:41 Найти цитируемый пост)
Я против такого объяснения

а я за. потому что Рихтер, я считаю, более авторитетен и компетентен в таких вопросах, его книгой не одна сотня программистов
воспользовалась. а то что ты говоришь, не более, чем твои домыслы.

Цитата(Alexeis @  7.1.2007,  23:41 Найти цитируемый пост)
Кто сказал, что все что имеется в dll экспортируется из нее?

никто(я в частности) нигде(в этой ветке) про это не говорил. все верно. что объявили, то и экспортруем. остальное - просто кусок данных.

Цитата(Alexeis @  7.1.2007,  23:41 Найти цитируемый пост)
Так то оно так. Формально доступ к ним хоть и можно получить, но что с ними делать? Одно дело атомарные типы, а другое объекты классов. Поскольку сами классы экспортировать нельзя, то сама программа и не может с ними работать. Программа может работать с объектами своих классов (описанных в ней). 

"объекты классов"...так объекты или классы? в делфи объекты(object) оставлены для обратной совместимости и не рекомендованы к использованию. сорь, придираюсь к тексту... так, о чем мы?
полностью согласен с тем, что обмен ЭКЗЕПЛЯРАМИ классов между DLL и приложенияем не есть хорошо. но в делфи в частности можно, используя например FastShareMem, передавать и стринги и классы(ссылки) между кодом в DLL и приложением.

про последний абзац... приведенные примеры неверны, имхо.
потому, что окно - это объект ядра системы, память, где он распологается, мы напрямую трогать не должны."хе-хе" ;) это участь драйверов, шлюзов, кода самого ядра. а хэндл, что мы имеем в результате работы CreateWindowEx и набор функций для изменения его состояния из системной dll (которая, кстати, тоже в АП процесса висит), это только рычажки, дергая которые мы изменяем объект ядра.

Цитата(Alexeis @  7.1.2007,  23:41 Найти цитируемый пост)
Во времена процедурного программирования, атомарных типов ситуация была похожа на то что описывается у Рихтера.

ой, ну что ты, Рихтер, по сравнению с "современным" программистом, как мы с вами, просто неандерталец какой-то!  smile 
да все ООП по сути обертка над процедурным программированием, сделанная для удобства/изза лени программистов.
и вообще на более низком уровне ООП нет никакого ООП, интерфейсов (СОМ), и проч. высокоуровневого бреда,
есть только набор функций ядра. которые в свою очередь являются набором команд ЦПУ.

и ВООБЩЕ, из-за чего весь сыр-бор?!
для меня очевидно, что код и данные динамически загружаемых библиотек в процессе находится в его ВАП. все. точка.
пока ничего внятного ("радиопремник у Васи" не в счет), опровергающее это утверждение, я не услышал.
ни ссылок на известные труды по архитектуре Windows, ни ссылок на MSDN. несерьезно как-то товарищи.

  с уважением.

з.ы. простите, если что, за то, что перешел на "ты") "Вы"кать надоело.



--------------------
There are always someone smarter than you...
PM MAIL   Вверх
MetalFan
Дата 8.1.2007, 01:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



вот код:

библиотека:
Код

library projDLL;
uses
  Windows;

  procedure Proc2; stdcall;
  begin
    MessageBox( 0, 'Message From Not Exported Proc','Message', 0 );
  end;

  function func1: Pointer; stdcall;
  begin
    Result := @Proc2;
  end;

  exports
     func1 Name 'func';

begin
end.


проект:
Код

program ProjDLLProc;

uses
  Windows;

  type
    TProc = procedure; stdcall;
    TFunc = function: Pointer; stdcall;
  var
    libHandle: DWORD;
    Proc: TProc;
    Func: TFunc;
    lPt: Pointer;
begin
   libHandle := LoadLibrary( 'projDLL.dll' );
   if libHandle <> 0 then
   begin
     lPt := GetProcAddress( libHandle, 'func' );
     if lPt <> nil then
     begin
       @Func := lPt;
       lPt := Func;
       if lPt <> nil then
       begin
         @Proc := lPt;
         Proc;
       end;
     end;

   end;
end.


и вот давайте, объясните. каким образом здесь чего по вашему работает?!
ведь про Proc2 ну ничего сама программа не знает. ну не иначе в одном АП код DLL и код приложения находятся?
или продолжим дебаты про применик у соседа?


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Romikgy
Дата 8.1.2007, 02:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 26
Всего: 146



Цитата(MetalFan @  8.1.2007,  00:17 Найти цитируемый пост)
и ВООБЩЕ, из-за чего весь сыр-бор?!

так что же ты так разошелся?
Имхо Рихтер тоже человек, как ты , как я он тоже мог ошибаться!
и если порытся по нету, найдешь много сторонников его , так много и противников его !( имхо это не показатель)

Цитата(MetalFan @  8.1.2007,  00:17 Найти цитируемый пост)
а что о них говорить? кусок зарезервированного/занятого АП, доступный на чтение и на запись.

А то говорит , что эти данные не располагаются на стеке, имхо
Цитата(MetalFan @  8.1.2007,  00:17 Найти цитируемый пост)
ну да, все ясно. но DLL попрежнему ничем не владеет) все созданные функциями DLL объекты/классы распологаются в АП процесса и являют для него просто кусками памяти с данными, разве не так?

smile или владеет всем...
Цитата(MetalFan @  8.1.2007,  00:17 Найти цитируемый пост)
"объекты классов"...так объекты или классы? в делфи объекты(object) оставлены для обратной совместимости и не рекомендованы к использованию. сорь, придираюсь к тексту... так, о чем мы?

здесь с терминалогией разобратся имхо надо
Цитата(MetalFan @  8.1.2007,  00:47 Найти цитируемый пост)
вот код:

к чему ты его привел?


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
MetalFan
Дата 8.1.2007, 03:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



Цитата(Romikgy @  8.1.2007,  02:30 Найти цитируемый пост)
А то говорит , что эти данные не располагаются на стеке, имхо

причем тут стек? стек потока тоже в ВАП находится.

Цитата(Romikgy @  8.1.2007,  02:30 Найти цитируемый пост)
к чему ты его привел? 

к тому, что он показывает, что код загруженной DLL находится в том же ВАП, где и код программы.


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Alexeis
Дата 8.1.2007, 03:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Цитата(MetalFan @  8.1.2007,  01:17 Найти цитируемый пост)
полностью согласен с тем, что обмен ЭКЗЕПЛЯРАМИ классов между DLL и приложенияем не есть хорошо. но в делфи в частности можно, используя например FastShareMem, передавать и стринги и классы(ссылки) между кодом в DLL и приложением.


  Вот пожалуйста, а еще говоришь, что хорошо объяснил учебник Рихтера! Еще один наступил на те же грабли. Между тем, что иногда работает и всегда работает есть большая разница. FastShareMem - заставляет использовать обе программные единицы один общий менеджер кучи, только и всего. Не ужели не ясно, что объект класса TButton в программе и объект класса TButton в Dll это объекты совершенно разных классов. Передавать ссылку на объект можно только внутри программы или внутри Dll, но никак не между программой и Dll. Если передать ссылку в программу, то программа будет думать, что перед ней экземпляр ее класса TButton, тогда как на самом деле это экземпляр класса TButton dll. В результате будет тоже самое, что привести TButton к TLabel - т.е. к неопределенным последствиям. 
  Когда я говорил о передаче класса, я имелл виду именно передачу класса, а не что иное. Если бы Dll могла передать класс TButton программе и программа на основе него создала свой экземпляр объекта, то все было бы нормально. Но это невозможно, потому программа приводит объект к чужому классу. Последствия такого приведения будут приводить к невероятным ошибкам.


Цитата(MetalFan @  8.1.2007,  01:17 Найти цитируемый пост)
потому, что окно - это объект ядра системы, память, где он распологается, мы напрямую трогать не должны."хе-хе" ;) это участь драйверов, шлюзов, кода самого ядра. а хэндл, что мы имеем в результате работы CreateWindowEx и набор функций для изменения его состояния из системной dll (которая, кстати, тоже в АП процесса висит), это только рычажки, дергая которые мы изменяем объект ядра.

Цитата(MetalFan @  7.1.2007,  22:12 Найти цитируемый пост)
Кроме того, любые созданные кодом DLL объекты принадлежат вызывающему потоку или процессу — DLL ничем не владеет.


Вот пожалуйста и опровержение. Объекты создает Dll, но они совершенно не принадлежат процессу. 

Цитата(MetalFan @  8.1.2007,  01:17 Найти цитируемый пост)
да все ООП по сути обертка над процедурным программированием, сделанная для удобства/изза лени программистов.
и вообще на более низком уровне ООП нет никакого ООП, интерфейсов (СОМ), и проч. высокоуровневого бреда,
есть только набор функций ядра. которые в свою очередь являются набором команд ЦПУ.


  Не все так просто. Современные объекты уже сильно развитые сущности. Развитые механизмы управления уже не позволяют обращаться с ними как со структурами имеющими ссылки на функции. Так что приведенный пример это тоже уже дела минувших дней. Простейшие объекты такие как строки или  динамические массивы требуют всего лишь общего менеджера памяти, но такие сложные объекты как форма не позволят производить такие вещи. Впервые я столкнулся с этой проблемой при передаче компонента TImage. Он является уже развитым представителем. Банальная операция чтения пиксела приводит к уничтожению его содержимого, а все потому, что он не может идентифицировать свой контейнер изображения и делает вывод, что он просто не создан и создает его заново уничтожая старый. Он то ожидает там объект класса TBitmap описанного в программе, а находит объект класса TBitmap описанного в Dll. Я же говорил уже что это различные классы. Информация о классах во время исполнения один из механизмов, который перестает работать при передаче объектов. Результат неправильной работы чреват неопределенными последствиями.  
  Это как минимум, а если представить, что Dll и программа компилировались разными версиями компилятора, что очень часто и бывает, то такая передача окончится катастрофой при первом же обращении к методам или данным. А если говорить о разных языках программирования, то устройство классов там вообще различное. Объект должен создаваться только в Dll и управляться по средством экспортирумых функций. Причем передача указателя на объект в программу вообще недопустима. Объект созданный в Dll должен быть в ней же и уничтожен. Программа получает только идентификатор объекта позволяющий отличить его от другого объекта созданного той же Dll. Для окон это будет глобальный идентификатор, но что-то у меня сомнения, что он создается именно в системной памяти. Интерфейс является таким же идентификатором, но создан для реализации механизмов ООП т.е. для доступа к объекту которым фактически владеет Dll, хотя формально он и принадлежит программе, так как находится в ее адресном пространстве, которая сама по себе не умеет с ним работать. 

Цитата(MetalFan @  8.1.2007,  01:17 Найти цитируемый пост)
ой, ну что ты, Рихтер, по сравнению с "современным" программистом, как мы с вами, просто неандерталец какой-то!

  Винда сама по себе до сих была процедурно-ориентированной. Но на сегодняшний день они полностью отказались от этой концепции и все новые технологии строятся по принципам ООП. Вместо со старыми принципами вида пошла по пути отказа от механизмов Dll, как устаревших и не способных реализовать современные объектные концепции. Dll будут оставаться как механизм совместимости старого софта. 
  Не нужно думать, что все что он написал это чисто его выводы и сведения. Часть это банальная адаптация текста MSDN, который никогда не отличался доступностью изложения. Меньше нужно молиться на "богов". Я продолжаю настаивать на том, что объяснение Рихтера не самое удачное, потому что благодаря нему каждый второй программист ступает на те же вилы. Dll - это чужой модуль и как бы винда его не породняла с программой, он все равно останется для нее чужим. А к чужакам нужно  
 относиться всегда с опаской и использовать только те механизмы, которые документированы.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
aktuba
Дата 8.1.2007, 03:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


Профиль
Группа: Завсегдатай
Сообщений: 1915
Регистрация: 24.4.2006
Где: Планета Земля

Репутация: 16
Всего: 38



Цитата

Не нужно думать, что все что он написал это чисто его выводы и сведения. Часть это банальная адаптация текста MSDN, который никогда не отличался доступностью изложения. Меньше нужно молиться на "богов". Я продолжаю настаивать на том, что объяснение Рихтера не самое удачное, потому что благодаря нему каждый второй программист ступает на те же вилы. Dll - это чужой модуль и как бы винда его не породняла с программой, он все равно останется для нее чужим. А к чужакам нужно  
 относиться всегда с опаской и использовать только те механизмы, которые документированы. 


Вот и про это я и пытался в аське объяснить. Рихтер хорошо, не не значит, что абсолютно правильно. 

Все же я был прав, Metal?

P.S.: специально для тебя перевод MSDN откопал:

Цитата

Функция точки входа использует функцию TlsAlloc, чтобы назначать индекс TLS всякий раз, когда процесс загружает DLL. Каждый поток может тогда использовать этот индекс, чтобы сохранить указатель на свой собственный блок памяти.


Вот здесь.

Незнаю, насколько достоверно, но...

Во, еще нашел =). У Рихтера заметь! Читаем, Глава 17:

Цитата

Проецирование в память EXE- и DLL-файлов

...

Резервирует регион адресного пространства - такой, чтобы в него мог поместиться заданный DLL-файл. Желательное расположение этого региона указывается внутри самого DLL-файла. По умолчанию Microsoft Visual C++ присваивает DLL-модулям базовый адрес 0x10000000 (в 64-разрядной DLL под управлением 64-разрядной Windows 2000 этот адрес может быть другим). При компоновке DLL это значение можно изменить с помощью параметра /BASE. У всех стандартных системных DLL, поставляемых с Windows, разные базовые адреса, чтобы не допустить их перекрытия при загрузке в одно адресное пространство. 
Если зарезервировать регион по желательному для DLL базовому адресу не удается (из-за того, что он слишком мал либо занят каким-то еще EXE- или DLL файлом), система пытается найти другой регион. Но по двум причинам такая ситуация весьма неприятна. Во-первых, если в DLL нет информации о возможной переадресации (relocation information), загрузка может вообще не получиться. (Такую информацию можно удалить из DLL при компоновке с параметром /FIXED. Это уменьшит размер DLL-файла, но тогда модуль должен грузиться только по указанному базовому адресу). Во-вторых, системе приходится выполнять модификацию адресов (relocations) внутри DLL. В Windows 98 эта операция осуществляется по мере подкачки страниц в оперативную память. Но в Windows 2000 на это уходит дополнительная физическая память, выделяемая из страничного файла, да и загрузка такой DLL займет больше времени. 
Отмечает, что физическая память, связанная с зарезервированным регионом, — DLL-файл на диске, а не страничный файл. Если Windows 2000 пришлось выполнять модификацию адресов из-за того, что DLL не удалось загрузить по желательному базовому адресу, она запоминает, что часть физической памяти для DLL связана со страничным файлом.


Теперь тоже говоришь, что у DLL нет адресного пространства???

Это сообщение отредактировал(а) aktuba - 8.1.2007, 08:10


--------------------
user posted image
PM MAIL WWW Skype   Вверх
Alexeis
Дата 8.1.2007, 10:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



aktuba, В данном случае речь как раз о регионе виртуального адресного пространства exe. Это и есть тот диапазон адресов куда будет отображаться образ Dll.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
MetalFan
Дата 8.1.2007, 11:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



Alexeis, про RTTI я тоже в курсе. тут она "своя" для процесса и DLL, созданной в delphi. но этот механизм тоже наверняка можно "довести до ума", т.е. объединить две RTTI. что тоже не есть хорошо, ибо после выгрузки библиотеки придется их как-то "расклеивать".
но это, повторюсь, высокоуровневые механизмы, надстройка ООП над обычным ПОП. реализация ООП в разных языках, да что там языках, разных версиях Delphi - различается. и еслиб Borland и сделала механизм, позволяющий использовать одну RTTI для процесса и "родных" ДЛЛ, то легче от этого бы не стало, глюков бы не убавилось.

aktuba, ничего тебе непонятно.
приведенная тобой цитата как раз и говорит о том, что DLL загружается в ВАП процесса. Что в DLL должен быть указан базовый адрес в ВАП процесса, куда ее в идеале нужно "отразить"/загрузить,нет у DLL "своего" АП с другой адресацией. нет ни у процесса ни у DLL прямого доступа к реальной физической памяти.
один только ты это не понимаешь.



--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Alexeis
Дата 8.1.2007, 12:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 109
Всего: 459



Цитата(MetalFan @  8.1.2007,  11:34 Найти цитируемый пост)
но это, повторюсь, высокоуровневые механизмы, надстройка ООП над обычным ПОП. реализация ООП в разных языках, да что там языках, разных версиях Delphi - различается. и еслиб Borland и сделала механизм, позволяющий использовать одну RTTI для процесса и "родных" ДЛЛ, то легче от этого бы не стало, глюков бы не убавилось.


  С основами ассемблера я знаком и знаю, что на уровне процессор поддерживается только процедурное программирование. Я не сомневаюсь, что при большом желании такие ситуации можно разрулить, но ЗАЧЕМ???!!! Такое можно оправдать только учебными целями. Delphi не стоит на месте и то что удалось разрулить ручками в одной версии вероятно не удастся в другой. Если такие задачи вправду так остро стоят, то стоит задуматься о переходе на .net там все модули (сборки) изначально объектные и таких проблем просто не возникает. 
  Это не глюки, а результат использования недокументированных возможностей. Никто этим заниматься не будет. Для win32 борланд написала механизм BPL. В его основе лежит то, что класс определен в отдельном модуле, а все прочие программные модули используют единственное и уникальное описание класса. Это точно будет работать, потому тут механизм передачи объекта документирован, а при возникновении настоящего глюка всегда можно обратиться в поддержку Borland.
  И уж для коллекции еще раз приведу 3й механизм. Интерфейсов созданный для совместимости с технологией COM и использования объектов созданных вне приложения, хоть и расположенных в ее адресном пространстве. Для меня все равно этот механизм понятней как отношения клиента и сервера, нежели отношение владения объектом, в то время как ничего кроме как передачи указателя программа самостоятельно делать не может. Кроме того скажем при использовании COM объекта по средством чужого приложения не позволяет получить даже сам указатель на реальный объект. Я считаю, что все перечисленное хорошо объединяется в группу отношения взаимодействия чужого модуля с программой.

  Dll же как чисто процедурный механизм может считаться дружественным (т.е. модуль свой и все в нем свое). Но времена процедурного программирования уже прошли и Delphi определяет уже чисто объектную модель создания программы. В этой объектной модели отношение программа <-> Dll уже не могут строится по схеме дружественности, за исключением взаимодействия программа <-> ОС, где реализуется подход совместимости с процедурным программированием, который лежит в основе API и который на настоящий момент уже, очевидно, устарел.

Цитата(MetalFan @  8.1.2007,  11:34 Найти цитируемый пост)
нет у DLL "своего" АП с другой адресацией.

Да личного АП нет, в первом посте под своим АП я подразумевал, то АП куда она первоначально загружается. Физически библиотека там, потому оно как бы ее, но на самом деле это некая системная область управляемая ОС. Кто кроме нее в этой области фиг его знает smile. Может это, вообще, просто физическое адресное пространство.


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
MetalFan
Дата 9.1.2007, 09:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 62
Всего: 128



Цитата(Alexeis @  8.1.2007,  12:43 Найти цитируемый пост)
Да личного АП нет, в первом посте под своим АП я подразумевал, то АП куда она первоначально загружается. 

 smile *THUMBS UP*
из-за утверждения о "Отдельном АП у DLL и у приложения" спор и начался))))
все, дискуссию считаю завершенной! спасибо! интересно было мнениями обменятся )


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1358 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.