Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 1 642

/ вопрос решён /

Здравствуйте, уважаемые эксперты!
Снова работаю с плагинами, мне необходимо реализовать динамическую загрузку сразу нескольких плагинов!
Мой вариант "в цикле" как видно провальный, мне не хватает опыта для реализации данной идеи.

for i:=0 to pluglist.count-1 do begin
PlugHandle := LoadLibrary(pchar(pluglist.Strings[0]));
if PlugHandle<>0 then begin
@proc1 := GetProcAddress(plugHandle,'proc1');
@proc2:= GetProcAddress(plugHandle,'proc2');
@func1 := GetProcAddress(plugHandle,'func1');
@func2:= GetProcAddress(plugHandle,'func2');
//функции используются в других процедурах...
if @proc1 <> nil then
proc1;
if @proc2 <> nil then
proc2;
end;
end;

Вот такая белиберда. Выходит так, что грузится только последний плугин из списка. Как загрузить все плагины из списка сразу (я имею ввиду все процедуры и функции, содержащиеся в каждом)? Догадываюсь надо иметь кучу переменных proc1Х, чтобы хранить все функции... Надеюсь на помощь!

Phoenix Вопрос решён, но можно продолжить его обсуждение в мини-форуме

Вопрос задал: Phoenix (статус: Посетитель)
Вопрос отправлен: 1 июня 2008, 17:51
Состояние вопроса: решён, ответов: 2.

Ответ #1. Отвечает эксперт: Вадим К

Здравствуйте, Phoenix!
Ну а вся заковырка в этой строке PlugHandle := LoadLibrary(pchar(pluglist.Strings[0]));
вы всегда грузите только первый файл, не важно, сколько их там. Попробуйте заменить на PlugHandle := LoadLibrary(pchar(pluglist.Strings[i]));
А также, возможно, после загрузки надо добавить выгрузку с помощью FreeLibrary или заводьте массив для хендлов плугинов.

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 1 июня 2008, 18:33
Оценка за ответ: 5

Комментарий к оценке: Спасибо, очень прошу глянуть сообщение на мини-форуме вопроса

Ответ #2. Отвечает эксперт: min@y™

В дополнение к ответу Вадима К.

Цитата:

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


Хэндлы удобнее хранить в классе TList, откуда их в цикле извлекать для FreeLibrary(). Адреса функций ProcX и FuncX тоже можно хранить в соответствующих экземплярах TList.

Ответ отправил: min@y™ (статус: Доктор наук)
Время отправки: 2 июня 2008, 08:19
Оценка за ответ: 5

Комментарий к оценке: отлично, как это я сразу не додумался, попробую

Мини-форум вопроса

Всего сообщений: 33; последнее сообщение — 4 июня 2008, 08:05; участников в обсуждении: 2.

Страницы: [1] [2] [Следующая »]

Phoenix

Phoenix (статус: Посетитель), 1 июня 2008, 19:06 [#1]:

Вадим, с нулем опечатка!! неужели придется использовать массив хендлов?
что-то типа:
var
plugs : array of THandle;
//...............................
for i:=0 to pluglist.count-1 do begin
plugs[i]:= LoadLibrary(pchar(pluglist.Strings[i]));
//...............................

вот только вопрос: обязательно ли нужно определять границы массива?
plugs [0..9] : array of THandle;
//очень плохо, т.к. плагинов с списке может быть больше!

Если обязательно, то можно ли ввети динамический массив? что-то типа:
SetLength(plugs, pluglist.count); //нехорошо!


и вопрос на засыпку: можно ли использовать динамические массивы в DLL?
Phoenix

Phoenix (статус: Посетитель), 1 июня 2008, 19:18 [#2]:

и еще, как это я не подумал написав, выходит надо ввести массив функций (!) а такое не возможно?
а хендл использовать один и очищать после каждого плагина FreeLibrary(Handle);

-----------------------
PlugLoad : array of function(mes:string):pchar //смешно даже
//даже не представляю как это будет выглядеть
PlugLoad[i]('приивет'); //катаюсь по полу
Phoenix

Phoenix (статус: Посетитель), 1 июня 2008, 19:23 [#3]:

тьфу, перепутал все...
@proc1:= GetProcAddress(plug[i],'proc1'); ТАК*?
это выглядит не так глупо как моё предыдущее сообшщение
Phoenix

Phoenix (статус: Посетитель), 1 июня 2008, 19:28 [#4]:

нет, действительно надо вводить массив функций, пердыдущее моё сообщение не спасает положение я в тупике....
Вадим К

Вадим К (статус: Академик), 1 июня 2008, 19:57 [#5]:

Я бы на вашем месте создал структуру (а лучше класс), который будет инкапсулировать в себя длл. То есть, там будет и хендл, и объёртка для процедур.
А потом для всего этого динамический массив (а ещё лучше - класс-наследник TList).
Скрыв таким образом всю "внутреннюю кухню", вы лишитесь всех проблем.

Массив без границ можно объявлять, это динамический массив.
Но для него надо использовать SetLength и выставлять размеры.
Но эту функцию можно применять к массиву много раз и менять размер.
Галочка "подтверждения прочтения" - вселенское зло.
Phoenix

Phoenix (статус: Посетитель), 1 июня 2008, 20:11 [#6]:

ого! половину ваших терминов я не понял... до создания классов я еще не дорос, поэтому как не постараюсь, такое чудо не смастерю. НУ ладно, спасибо и на этом, может придётся и отказаться от всего, т.к. не вижу способа реализации.
Вадим К

Вадим К (статус: Академик), 1 июня 2008, 20:43 [#7]:

Кода то там на один юнит. главное взяться. попробуйте на основе record и массивов
Галочка "подтверждения прочтения" - вселенское зло.
Phoenix

Phoenix (статус: Посетитель), 1 июня 2008, 20:50 [#8]:

конечно ж попробую, только у меня ж опыта в таких делах нет, буду ковыряться, в итоге - ничего!
Вадим К

Вадим К (статус: Академик), 1 июня 2008, 21:25 [#9]:

Тогда надо читать книжжки, статьи, пробовать разбить задачу на более простые и по мере надобности формулировать вопросы.
Галочка "подтверждения прочтения" - вселенское зло.
Phoenix

Phoenix (статус: Посетитель), 2 июня 2008, 14:27 [#10]:

делаю вот так, создаю класс:
type
TPlugs = class
private
NazvPluga : String;
HandlPluga : Thandle;
public
property PlugName : String
read NazvPluga;
property PlugHandle : THandle
read HandlPluga;
constructor Create(const NazvPluga : String;
const HandlPluga : Thandle);
end;

//обязательно
spisok:TList
далее завожу динамический массив THandlе'ов - masshand, определяю размер:

SetLength(massplugs, pluglist.count);

//при этом pluglist заполняется ранее. потом в цикле заполняется spisok:
for i:=0 to pluglist.count-1 do begin
spisok.Add(TPlugs.Create(pluglist.Strings[i], masshand[i]));
//далее грузим в хэндл плуг, в том же цикле:
TPlugs(spisok[i]).PlugHandle:=LoadPlugin(TPlugs(spisok[i]).PlugName);
//далее допустим, что мы создали список процедурами и список с функциями procspisok, funcspisok:
//все в том же цикле определяем:
при этом класс процедурTProc имеет 2 поля-свойства - имя функции (name:string) и саму процедуру (procdura:procedure)
TProc(procspisok[i]).procdura:= GetProcAddress(TPlugs(spisok[i]).PlugHandle,TProc(procspisok[i]).name);
//далее тоже самое с функциями
end;

кажется слишком громоздко получается? да и кое-что не сходится! прошу поправить
Вадим К

Вадим К (статус: Академик), 2 июня 2008, 15:20 [#11]:

а зачем массив хендлов заводить? и пусть класс только получает имя плугина(имя файла) и сам уже лезит, загружает. Хендл длл должен быть скрыт внутри класса - другим он не надо.
Галочка "подтверждения прочтения" - вселенское зло.
Phoenix

Phoenix (статус: Посетитель), 2 июня 2008, 15:48 [#12]:

насколько я знаю, для того чтобы скрыть поле класса, надо добавить его в секцию private,так?
TPlugs = class
private
HandlPluga : Thandle;
property PlugHandle : THandle
read HandlPluga;
protected
public
NazvPluga : String;
property PlugName : String
read NazvPluga;
constructor Create(const NazvPluga : String;const HandlPluga : Thandle);
end;
Вадим К

Вадим К (статус: Академик), 2 июня 2008, 16:23 [#13]:

приватные свойства делать не нужно
protect лучше перевести в public - иначе доступа к ним не видать
Галочка "подтверждения прочтения" - вселенское зло.
Phoenix

Phoenix (статус: Посетитель), 2 июня 2008, 16:30 [#14]:

понятно, а как же быть с конструктором? spisok.Add(TPlugs.Create(pluglist.Strings[i], XXXXXXX));
XXXXXXX - тут должно быть хэндл:cardinal, откуда его взять? если не заводить массив хэндлов?
Вадим К

Вадим К (статус: Академик), 2 июня 2008, 16:39 [#15]:

а не надо хендл передвать!
пусть класс сам подгрузит библиотеку.
и pluglist тоже не надо.
Галочка "подтверждения прочтения" - вселенское зло.
Phoenix

Phoenix (статус: Посетитель), 2 июня 2008, 16:44 [#16]:

=)) вконец запутался я...
pluglist - это список плагинов, он нужен, для того чтоб выпонить цикл загрузки плагинов. похоже, я не понимаю самой идеи. может в класс надо вводить процедуру загрузки?
Вадим К

Вадим К (статус: Академик), 2 июня 2008, 16:58 [#17]:

в цикле ищем длл и для каждой найденной, создаём объект и передаем имя. А в конструкторе выполняем загрузку, анализ длл.
и получается, что список уже не надо. Зачем дублировать инфу.
Галочка "подтверждения прочтения" - вселенское зло.
Phoenix

Phoenix (статус: Посетитель), 2 июня 2008, 17:11 [#18]:

да если и дублировать, все-равно нет материала для разбора. конкретнее мне все это не представить.
Вадим К

Вадим К (статус: Академик), 2 июня 2008, 17:13 [#19]:

в чём конкретно проблема? в том, что бы правильно разделить код?
Галочка "подтверждения прочтения" - вселенское зло.
Phoenix

Phoenix (статус: Посетитель), 2 июня 2008, 17:14 [#20]:

а вообще есть более простые методы решения такой довольно специфической задачи? неужели кроме меня никто с таким не сталкивался?

Страницы: [1] [2] [Следующая »]

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:50
Выполнено за 0.03 сек.