Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.10.31;
Скачать: CL | DM;

Вниз

DLL И Interface   Найти похожие ветки 

 
Grigsv   (2004-09-23 17:06) [0]

Добрый день, всем.
Проблемма :
1. Создал DLL
2. динамически загрузил ее в программе
3. Получил адрес функции и из нее получил адрес объекта.
4. Запросил у объекта интерфейс
5. Выполнил какие-то действия, Без видимых ошибок. ( Вызвал ShowMessage ;) )
6. освободил интерфейст.
7. Освободил библиотеку
Проблемма : на 6 или 7 шаге программа рушится.  Если работать без интерфейсов, то все нормально. Глюк. Помогите, объясните в чем дело, пожалуйста. Кусок кода ниже :

procedure TForm2.Button1Click(Sender: TObject);

var
 HI : HInst;
 Exec : function : TInterfacedObject; stdcall;
 O : TInterfacedObject;
 sh : IShow;
begin
 HI := LoadLibrary("LIB.Dll");
 if HI > 0 then begin
   Exec := GetProcAddress( HI, "GetObj" );
   if Assigned( @Exec ) then begin

     O := Exec;

     if Assigned( O ) then begin
       sh := O as IShow;
       if Assigned(sh) then begin
         sh := o as IShow;
         sh.Mess;
       end;
     end;
   end;
   FreeLibrary( HI );
 end;
end;


 
Digitman ©   (2004-09-23 17:20) [1]

собери оба проекта с ран-тайм пакетами


 
Digitman ©   (2004-09-23 17:25) [2]

вру

рантайм-пакеты, конечно. не помешают, но ... где у тебя явный шаг 6 ?
он выполняется у тебя неявно ПОСЛЕ шага 7, оттого и проблема


 
Cobalt ©   (2004-09-23 17:47) [3]

Хм, а не лучше ли в функции декларировать, что она возвращает именно интерфейс?


 
Cobalt ©   (2004-09-23 17:47) [4]

Хм, а не лучше ли в функции декларировать, что она возвращает именно интерфейс?


 
Grigsv   (2004-09-24 09:06) [5]

Эксперементировал много, вот и стер строку с освобождением интерфейса. Но проблемма все равно осталась. С этой строкой, или без нее.

....
     if Assigned( O ) then begin
       sh := O as IShow;
       if Assigned(sh) then begin
         sh := o as IShow;
         sh.Mess;
         sh := nil; -- <<<<<<<<<<<<<<
       end;
     end;
....


 
Grigsv   (2004-09-24 09:18) [6]

Проверил идею Cobalt © с функцией возвращающей интерфейс. Сработало, как не странно. :/

procedure TForm2.Button1Click(Sender: TObject);
var
 HI : HInst;
 Exec : function : IShow; stdcall;
 sh : IShow;
begin
 HI := LOadLibrary("LIB.Dll");
 if HI > 0 then begin
   Exec := GetProcAddress( HI, "GetIShow" );
   if Assigned( @Exec ) then begin
     sh := Exec;
     if Assigned(sh) then begin
         sh.Mess;
         sh := nil;
     end;
   end;
   FreeLibrary( HI );
 end;
end;


 
Grigsv   (2004-09-24 09:37) [7]

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


 
Digitman ©   (2004-09-24 10:06) [8]

нет, не вру

менеджеры памяти скорей всего разные

память под интерфейсный объект в ходе его конструирования выделяется экземпляром менеджера в ДЛЛ, а попытка освобождения этой памяти в ходе его разрушения осуществляется экземпляром менеджера в ЕХЕ

либо задействуй ShareMem либо собирай все с ран-тайм пакетами


 
Polevi ©   (2004-09-24 10:16) [9]

зачем жти извращения с LoadLibrary и GetProcAddress в данном случае
кто мешает использовать ActiveX library + CreateCom(Ole)Object


 
Cobalt ©   (2004-09-24 14:33) [10]

>Digitman ©   (24.09.04 10:06) [8]
А разве для интерфейсов не вызывается просто _Release? И освобождает память тот класс, который исполняет интерфейс


 
Grigsv   (2004-09-27 13:38) [11]

Для чего я все это устроил: Есть единая запускалочка для разных форм, которые пишутся разными людьми. Формы работают с базами данных через BDE. Каждый человек собирает свои формы в одну или несколько библиотек. Связь EXE с DLL через объект связи, который для каждой DLL свой. Он и рассказывает, что нужно для работы своей DLL ( пользователь и права доступа, TDatabase, протоколирование и др.), т.е. какие интерфейсы он поддерживает.

Спасибо Digitman ©   за идею по поводу ShareMem. Работает.

По поводу остальных идей :

Polevi , ActiveX  : Для меня проще так. Может со временем и прийду к идее ActiveX.

Cobalt ©, _Realise : Эту функцию на прямую вызывать нежелательно. Да и глюки все равно при таком подходе остались.


 
Cobalt ©   (2004-09-27 14:43) [12]

2 Grigsv   (27.09.04 13:38) [11]
>Cobalt ©, _Realise : Эту функцию на прямую вызывать нежелательно. Да и глюки все равно при таком подходе остались.
Эта фраза предназначалась не тебе. Потому ты её не понял :)


 
Grigsv   (2004-09-27 15:22) [13]

Cobalt, не надо хамить. Хамство не украшает человека.


 
Cobalt ©   (2004-09-27 17:09) [14]

2 Grigsv   (27.09.04 15:22) [13]
Я же говорю, это не тебе :)
Пояснения - ниже (чтобы ты въехал, о чём я был не согласен с Digitman ©)

>Digitman ©   (24.09.04 10:06) [8]
менеджеры памяти скорей всего разные

память под интерфейсный объект в ходе его конструирования выделяется экземпляром менеджера в ДЛЛ, а попытка освобождения этой памяти в ходе его разрушения осуществляется экземпляром менеджера в ЕХЕ


Т.к. освобождение памяти, выделенной под интерфейс, осуществляется объектом, исполняющим интерфейс, (он-то создан в ДЛЛ) то обращается он к своему менеджеру памяти, не так ли?
И ShareMem тут не при чём - особенно, если ДЛЛ-ка написана на С++ или VB.


 
Cobalt ©   (2004-09-27 17:10) [15]

А самому вызывать  _Release, конечно же, не стоит. Это сделает за тебя компилятор.



Страницы: 1 вся ветка

Текущий архив: 2004.10.31;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.049 c
4-1095923936
Svarog
2004-09-23 11:18
2004.10.31
DLL+ресурсы+контекстное меню = проблема


4-1095787846
Асякин
2004-09-21 21:30
2004.10.31
Защита информации


3-1096545389
asdfgh
2004-09-30 15:56
2004.10.31
Упаковка DBF-файла


14-1097703650
quickblack
2004-10-14 01:40
2004.10.31
Востановление rar


1-1098133413
Helios
2004-10-19 01:03
2004.10.31
HTML