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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вызов dll из разных мест, Она dll в большом модульном проекте 
:(
    Опции темы
Mailman
Дата 16.6.2006, 01:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Итак, пусть у нас есть некий проект, состоящий из exe и энного набора динамич библиотек. Многие из библиотек, а также exe вызывают функцию(и) одной dll. Сейчас это происходит статически. Проблема состоит в том, что к процессу приложения подгружается столько экземпляров dll, из скольки модулей она загружалась. Также, соответственно, процедура инициализации dll (между begin и end.) происходит такое же количество раз и каждая часть проекта работает со своим экземпляром.

Вопрос мой состоит в том, как сделать так, чтобы библиотека подгружалась 1 раз или хотя бы инициализировалась один раз (методы обхода этого не предлагать - сам умею). Я видел справку по DllProc, но сам попробовать пока не успел. Можно ли решить вопрос с помощью определения обработчика с помощью DllProc? Если да/нет, то как это сделать?

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


Эксперт
****


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

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



Код

procedure LibraryProc(reason:integer);
begin
case reason of
 DLL_PROCESS_ATTACH:begin
   
                   end;
 DLL_PROCESS_DETACH:begin

                   end;
end;
end;

begin
DLLProc:=@LibraryProc;
LibraryProc(DLL_PROCESS_ATTACH);
end. 
  

Это сообщение отредактировал(а) bems - 16.6.2006, 01:28


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Mailman
Дата 16.6.2006, 11:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Хм, мысь конечно интересная, но что это меняет? Всё равно DLL_PROCESS_ATTACH вызывается прикаждой подгрузке библ из каждого модуля (... LibraryProc(DLL_PROCESS_ATTACH); ...) Ты же сам так написал. Таким образом количество экземпляров и количество раз инициализации нисколько не изменилось.

ЗЫ Мож я что не так понял? 
PM MAIL   Вверх
Guedda
Дата 16.6.2006, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Подрывник
****


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

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



Цитата(Mailman @  16.6.2006,  12:23 Найти цитируемый пост)
ЗЫ Мож я что не так понял?

Как раз таки "да"...
Ты видишь, что он проинициализировал в процедуре заново константы DLL_PROCESS_ATTACH & etc...
И сделал, как ты можешь видить, их пустыми. 


--------------------
Ll 2
PM MAIL WWW ICQ Skype GTalk   Вверх
DragonFire
Дата 16.6.2006, 12:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 14.8.2005
Где: Москва

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



Guedda
Чет я не понял ниче, можешь коментарии расставить че это за строки, поподробнее... И куда это писать? в библиотеку? 


--------------------
PM MAIL ICQ   Вверх
Mailman
Дата 16.6.2006, 12:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Хм. Как я уже сказал у меня это не сработало.

Guedda, покажи мне плз то место в коде, где он их проинициализировал, может я просто этого не заметил?

Добавлено @ 12:37 
Да, это писать в библиотеку. Строки след-го содержания - присвоить указателю на обработчик системных вызовов в длл линк на процедуру LibraryProc, вызвать её при инициализации библиотеки. Внутри процедуры - case по случаю того, что же собственно произошло. 
PM MAIL   Вверх
drkot
Дата 16.6.2006, 13:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


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

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



Может так:
  загрузить библиотеку в главном модуле (loadlibrary)
  во вспомогательные передавать указатель и там находить нужную процедуру (GetProcAddress)


возможно получится напрямую адресс передавать (хотя сомнительно)
 


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
DragonFire
Дата 16.6.2006, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 725
Регистрация: 14.8.2005
Где: Москва

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



Хм. А вот это мне нравится. Спасибо, я попробую.

Напрямую... Хм. Не буду спрашивать, как. Просто за этой фразой была идея, или просто мысль такая?
Mailman. 


--------------------
PM MAIL ICQ   Вверх
drkot
Дата 16.6.2006, 14:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


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

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



Идея, не идея так предположение.
Если адресс кода процедуры для всей системы, а не для процесса то может сработать.
А для передачи можно много способов придумать. Начиная от банального - в виде параметра функции, до отображаемых файлов и реестра.

Добавлено @ 14:54 
Цитата(DragonFire @  16.6.2006,  14:35 Найти цитируемый пост)
 я попробую.

сообщи о результате, а то самому проверять щас времени нет  smile  


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
bems
Дата 16.6.2006, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Mailman @  16.6.2006,  01:17 Найти цитируемый пост)
Проблема состоит в том, что к процессу приложения подгружается столько экземпляров dll, из скольки модулей она загружалась
Нет. Происто увеличивается щетцик ссылок на библиотеку.
Цитата(Mailman @  16.6.2006,  01:17 Найти цитируемый пост)
Также, соответственно, процедура инициализации dll (между begin и end.)происходит такое же количество раз и каждая часть проекта работает со своим экземпляром.
Это правда только если один модуль загрузил длл, потом выгрузил, потом другой загрузил. Если подключаешь статически, то вообще иниц. она только один раз.
Цитата

DLL_PROCESS_ATTACH    
Indicates that the DLL is attaching to the address space of the current process as a result of the process starting up or as a result of a call to LoadLibrary. DLLs can use this opportunity to initialize any instance data or to use the TlsAlloc function to allocate a thread local storage (TLS) index.
During initial process startup or after a call to LoadLibrary, the operating system scans the list of loaded DLLs for the process. For each DLL that has not already been called with the DLL_PROCESS_ATTACH value, the system calls the DLL's entry-point function. This call is made in the context of the thread that caused the process address space to change, such as the primary thread of the process or the thread that called LoadLibrary.

 А код который я выше привел это как наглядно и похоже на стиль МС. Нв самом деоле из этого же кода видно, что DLL_PROCESS_ATTACH это и есть то что между begin-end. И виноват в єтом стартовый код длл от дельфей.

 


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Mailman
Дата 16.6.2006, 17:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(bems @  16.6.2006,  17:16 Найти цитируемый пост)
Это правда только если один модуль загрузил длл, потом выгрузил, потом другой загрузил. Если подключаешь статически, то вообще иниц. она только один раз.

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


Цитата(bems @  16.6.2006,  17:16 Найти цитируемый пост)
 Нв самом деоле из этого же кода видно, что DLL_PROCESS_ATTACH это и есть то что между begin-end. И виноват в єтом стартовый код длл от дельфей.

С этим согласен. Таким образом это подтверждает нерабочесть данного метода.


drkot, спасибо, я просто сразу не понял, что ты имел ввиду адрес процедуры полученный (GetProcAddress). Я попробую, тебе в ПМ напишу. 

Всё, мои вопросы кончились, спасибо всем. 
PM MAIL   Вверх
Демо
Дата 16.6.2006, 17:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Mailman @  16.6.2006,  01:17 Найти цитируемый пост)
и каждая часть проекта работает со своим экземпляром.


Ты уверен в этом?

LoadLibrary в адресное пространство загружает только одну копию DLL. 


--------------------
    
PM MAIL ICQ Skype   Вверх
drkot
Дата 16.6.2006, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Ищущий
***


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

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



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

Цитата(Mailman @  16.6.2006,  17:26 Найти цитируемый пост)
Всё, мои вопросы кончились, спасибо всем

думаю они только начались. 


--------------------
Ошибка не становится истиной по причине широкого распространения,
как и Истина не становится Ошибкой из-за того, что никто её не видит.
PM   Вверх
bems
Дата 16.6.2006, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(Mailman @  16.6.2006,  17:26 Найти цитируемый пост)
При старте приложения все модули загрузили библиотеку. Она проинициализировалась много раз.
Быть того не может. А с чего ты решил что инициализация была много раз? Как считал?

Цитата(drkot @  16.6.2006,  17:58 Найти цитируемый пост)
скорее всего проблема не в количестве загруженных копий библиотеки (она должна быть одна, есди винда не глючит   ), а то что видно как множество длл это наверное данные (переменные инициализированные в ней). 
А где они повторно инициализируются? Что вызывает LoadLibrary при повторном обращении к той же длл? Мне такие точки входа неизвестны.

Цитата(drkot @  16.6.2006,  17:58 Найти цитируемый пост)
думаю они только начались.  
и мне так кажется

 


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Mailman
Дата 17.6.2006, 22:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Нет нет нет. 

Во первых,  
Цитата(bems @  16.6.2006,  18:06 Найти цитируемый пост)
 Что вызывает LoadLibrary при повторном обращении к той же длл?
 
То, что к ней первый раз обращаются из некоего исполняемого файла (dll или exe)

Во вторых,
Цитата(bems @  16.6.2006,  18:06 Найти цитируемый пост)
Быть того не может. А с чего ты решил что инициализация была много раз? Как считал?

Ну, у примеру посмотрел в своём таск менеджере. Во вторых при инициализации я пишу на консоль строку, я читать умею, как она пишется 3 раза. =)

В третьих,
Цитата(Демо @  16.6.2006,  17:27 Найти цитируемый пост)
LoadLibrary в адресное пространство загружает только одну копию DLL. 

Да. Только вот статически или динамически, но LoadLibrary вызывается из каждого модуля по разу.


Цитата(Демо @  16.6.2006,  17:27 Найти цитируемый пост)
и каждая часть проекта работает со своим экземпляром.
    
Ты уверен в этом?

Нет, но по-моему это так. Теперь это и не важно. Хотя по теории я прав.

И наконец, я воспользовался методом drkotа. Спасибо огромное за помощь. Да, указатель на функцию или процедуру по ходу глобален, так он удачно передаётся из 1й длл в exe, а exe спокойно выполняет функцию. Ещё раз спасибо большое. Я закончил.

Для тех, кому интересно - просто пример кода:

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

function GetAddr: pointer;
var
 h: Thandle;
begin
 h:= LoadLibrary('..\..\Logger\code\modLogger.dll');
 result:= GetProcAddress(h, 'DoLog');
end;


EXE:
Код

var
 DoLog: function (MsgText: ShortString): TexResult;

begin
 @DoLog:= GetAddr;
 DoLog('fghfgh');
 readln;
end.


Вот собственно и решение проблемы. Дальше - архетиктурный момент моей системы, но с этим я уже всё придумал и успешно реализую. Удачи. 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

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

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

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

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


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

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


 




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


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

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