Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 31.10.2013, 00:12
govorun govorun вне форума
Новичок
 
Регистрация: 30.10.2013
Сообщения: 60
Версия Delphi: delphi 7
Репутация: 10
По умолчанию Ошибка при выгрузке DLL

Доброго времени суток ...
Из главного модуля программы происходит динамическая загрузка DLL.
В DLL вносятся данные, в том числе и с помощью OpenDialog, которые потом сохраняются в базу Interbase. После сохранения данных в базе предусмотрена выгрузка DLL.

Код программы:
Код:
unit Unit2;

interface

uses
  Windows, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Menus, DBGrids, StdCtrls, Grids, DBCtrls, DB, Mask;

type
TShowFormins=procedure(handle: Thandle); stdcall;
....

procedure TForm2.N4Click(Sender: TObject);
var
    dllins:thandle;
    ShowFormins:TShowFormins;

begin
    dllins:=LoadLibrary('ins.dll');
    @ShowFormins:=GetProcAddress(dllins, 'ShowFormins');
    ShowFormins(handle);
    freelibrary(dllins);

end;

Код DLL

Код:
unit insUnit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, DBCtrls, Mask, DB, IBCustomDataSet, IBDatabase,
  IBTable, Grids, DBGrids;

type
  TForm1 = class(TForm)
  ......

  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  procedure ShowFormins(handle: Thandle); export; stdcall;

implementation

{$R *.dfm}

procedure ShowFormins(handle: Thandle);
begin
    application.handle:=handle;
    form1:=tform1.create(application);
    form1.ShowModal;
    form1.Free;
 
end;

procedure TForm1.FormShow(Sender: TObject);
begin
    form1.IBTable1.Insert;
    form1.Button1.SetFocus;
    form1.dbmemo1.Clear;
    form1.DBEdit1.Clear;
    form1.DBEdit2.Clear;
    form1.DBEdit3.Clear;
    form1.DBEdit4.Clear;
    form1.DBEdit5.Clear;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
    with OpenDialog1, dbMemo1 do
    if Execute then
    Lines.LoadFromFile(FileName);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
      if IBTable1.Modified then
    DataSource1.DataSet.FieldByName('t_data').AsString:=formatdatetime('dd.mm.yyyy',now());
    IBTable1.Post;
    form1.dbmemo1.Clear;
    form1.DBEdit1.Clear;
    form1.DBEdit2.Clear;
    form1.DBEdit3.Clear;
    form1.DBEdit4.Clear;
    form1.DBEdit5.Clear;
      Form1.Close;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
    form1.IBTable1.Cancel;
    form1.Close;
end;

end.
Беда в следующем: если не использовать OpenDialog (с его помощью загружаеися файл в dbmemo и потом в поле BLOB базы данных) то все работает красиво и DLL выгружается из памяти (естественно без загрузки файла в базу).
При использовании OpenDialog DLL не выгружается и при повторной загрузке (без выхода из программы) выдает ошибку "I/O error for file 'имя базы'".
Выручайте, не могу найти где ошибка.... Спасибо.
Ответить с цитированием
  #2  
Старый 31.10.2013, 02:47
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Код:
application.handle:=handle;
Кто сказал, что application в DLL равен application-у в программе?
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #3  
Старый 31.10.2013, 05:37
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,015
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от angvelem
Код:
application.handle:=handle;
Кто сказал, что application в DLL равен application-у в программе?

Не, это правильно.
Неправильно другое.
Должно быть:
Код:
form1 := tform1.create(Nil);
Ответить с цитированием
  #4  
Старый 31.10.2013, 07:33
govorun govorun вне форума
Новичок
 
Регистрация: 30.10.2013
Сообщения: 60
Версия Delphi: delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от lmikle
Не, это правильно.
Неправильно другое.
Должно быть:
Код:
form1 := tform1.create(Nil);

Вместо
form1:=tform1.create(application);
????
Так вроде в библии Фленова написано.
Ответить с цитированием
  #5  
Старый 31.10.2013, 10:27
Аватар для Freeman
Freeman Freeman вне форума
Местный
 
Регистрация: 05.10.2012
Адрес: Санкт-Петербург
Сообщения: 576
Версия Delphi: 6
Репутация: выкл
По умолчанию

Нужно еще учитывать, что вызов OpenDialog порождает дополнительные потоки (так устроен "Проводник"), и они тоже могут вмешиваться.
__________________
Не стоит путать форумы с богадельнями. © Bargest
Ответить с цитированием
  #6  
Старый 31.10.2013, 11:13
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Нету здесь кода библиотеки вообще, ключевое слово library отсутствует

Проверок возможно не хватает, надо похоже так делать динамическую загрузку
Код:
procedure TForm2.N4Click(Sender: TObject);
var
    dllins:thandle;
    ShowFormins:TShowFormins;
begin
   try
    dllins:= LoadLibrary('ins.dll');
    if dllins <> 0 then
     begin
      @ShowFormins:=GetProcAddress(dllins, 'ShowFormins');
      if addr(ShowFormins) <> nil then
       ShowFormins(handle);
   finally
    freelibrary(dllins);
   end;
    end else showMessage ('DLL not found...');
end;
Ответить с цитированием
  #7  
Старый 31.10.2013, 21:36
govorun govorun вне форума
Новичок
 
Регистрация: 30.10.2013
Сообщения: 60
Версия Delphi: delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Freeman
Нужно еще учитывать, что вызов OpenDialog порождает дополнительные потоки (так устроен "Проводник"), и они тоже могут вмешиваться.

Этого я и боялся... Потоки....

Мот кто-нибудь поможет с кодом. Как процедуру с opendialog "привязать" к "потокам".

В программе для OpenDialog предусмотрена процедура выбора файла (имя файла не известно, но он текстовый) из одной конкретной директории и загрузки его в dbmemo. Т.е. OpenDialog не будет шариться по всему диску. Может предложите простую альтернативу OpenDialog.

А может проще из DLL exe-шник сделать, или это неразумное решение?

Спасибо.

Последний раз редактировалось govorun, 31.10.2013 в 22:16.
Ответить с цитированием
  #8  
Старый 01.11.2013, 01:31
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Не там собака порылась, диалог здесь не влияет. Собрал подобную библитеку - загружается, грузит текст в DBMemo и без ошибок нормально выгружается. Попробуйте на время отключить все обращения к IBTable1 и убедитесь в этом.

З.Ы.
Цитата:
Сообщение от govorun
...для OpenDialog предусмотрена процедура выбора файла (имя файла не известно, но он текстовый) из одной конкретной директории и загрузки его в dbmemo...
Свойства DefaultExt и InitialDir или флажок ofNoChangeDir в Options это решают вполне
Ответить с цитированием
  #9  
Старый 01.11.2013, 07:27
govorun govorun вне форума
Новичок
 
Регистрация: 30.10.2013
Сообщения: 60
Версия Delphi: delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alegun
З.Ы.Свойства DefaultExt и InitialDir или флажок ofNoChangeDir в Options это решают вполне

Чуть подробнее про это, если можно....
Спасибо
Ответить с цитированием
  #10  
Старый 01.11.2013, 10:26
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Цитата:
Сообщение от govorun
Чуть подробнее про это, если можно...
Да собсно из самих названий вытекает:

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

FileName - можно принудительно задать файл для выбора при первом запуске диалога в сборке, прям с путями.

Filter - Здесь мастером задаются наборы расширений и потом можно выбирать из списка нужные.

InitialDir - стартовая директория при показе диалога т.е. он откроется сразу в указанной папке.

Options - дополнительные варианты открытия окошка, если флажок ofNoChangeDir выставить в true, то изменить случайно директорию будет проблематично. Там много чего ещё есть всякого.
Ответить с цитированием
  #11  
Старый 01.11.2013, 19:06
govorun govorun вне форума
Новичок
 
Регистрация: 30.10.2013
Сообщения: 60
Версия Delphi: delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alegun
Попробуйте на время отключить все обращения к IBTable1 и убедитесь в этом.

Попробовал, на форме в DLL остались dbeditы - ни с чем не связанные, DBMEMO связан с opendialog и кноки закрывающие форму.
Запуская прогу. В диспетчере задач Память указана 1292 КБ (сам екзешник 868 КБ).
Прдгружаю DLL. В диспетчере задач Память указана 1924 КБ (сам DLL весит 628 КБ)
Запускаю opendialog. В диспетчере задач Память указана 3756 КБ)
Закрываю DLL. В диспетчере задач Память указана 3100 КБ)

Получается что DLL не выгружается

У меня в этой программе есть еще одна аналогичная библиотека. Так вот после "якобы выгрузке первой" вторая не загружается с той же ошибкой

В общем пока ни один совет не помог....

Вот чего пмшет:

Proect XXX.exe raised excepyion class EIBInterbaseError with message "I/O error for file "имя базы""
Error while trying to open file.
Операция успешно завершена.
Process stopped. Use step or run to continue.

И после закрытия сообщения об ошибке выделяет в коде программы вот эту строку

freelibrary(dllins);

Где-то читал что можно сделать подобный opendialog только применением Listview или Richedit. Может подскажите код?

Цитата:
Сообщение от cotseec
код dll, что приведен в первом посте и есть весь код библиотеки?

Там код формы, которая находится в DLL

Код:
library ins;

uses
  SysUtils,
  forms,
  Classes,
  insUnit1 in 'insUnit1.pas' {Form1};

{$R *.res}

    exports ShowFormins;

begin
end.

Последний раз редактировалось M.A.D.M.A.N., 01.11.2013 в 23:32.
Ответить с цитированием
  #12  
Старый 01.11.2013, 22:46
Аватар для cotseec
cotseec cotseec вне форума
Активный
 
Регистрация: 16.07.2008
Сообщения: 353
Версия Delphi: D7,TDE06,RAD09
Репутация: 1443
По умолчанию

код dll, что приведен в первом посте и есть весь код библиотеки?
Цитата:
Сообщение от Alegun
Нету здесь кода библиотеки вообще, ключевое слово library отсутствует
__________________
Понять, что хочет заказчик - бесценно, ведь он платит MasterCard
Ответить с цитированием
  #13  
Старый 02.11.2013, 07:05
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Повторюсь, OpenDialog здесь ни причём
Цитата:
Сообщение от govorun
Вот чего пмшет:

Proect XXX.exe raised excepyion class EIBInterbaseError with message "I/O error for file "имя базы""
Error while trying to open file.
Операция успешно завершена.
Process stopped. Use step or run to continue.
Это означает, что ошибка вываливается при попытке открыть файл "имя базы" на диске т.е. вероятно его не видно (пути не верны). Здесь что-то с самой базой, если не верите, то попробуйте временно диалог не использовать, а в клике кнопки оставьте такое
Код:
procedure TForm1.Button1Click(Sender: TObject);
begin
 // грузим в дибимемо файл напрямую
    dbMemo1.Lines.LoadFromFile('SomeText.txt');
end;
ошибка так и останется, хоть диалог и не вызывается.

Оффтоп: Понимаю, после бейсика наверное тяжело в другую среду вживаться но пжлст, сами пока выводы не делайте что работает, что нет, что выгружается, пусть это делают другие...
Ответить с цитированием
  #14  
Старый 02.11.2013, 09:55
govorun govorun вне форума
Новичок
 
Регистрация: 30.10.2013
Сообщения: 60
Версия Delphi: delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от Alegun
Здесь что-то с самой базой, если не верите, то попробуйте временно диалог не использовать, а в клике кнопки оставьте такое
Код:
procedure TForm1.Button1Click(Sender: TObject);
begin
 // грузим в дибимемо файл напрямую
    dbMemo1.Lines.LoadFromFile('SomeText.txt');
end;
ошибка так и останется, хоть диалог и не вызывается.


Попробовал...
Все работает. В менеджере задач наблюдал за памятью занятой программой... Библиотека выгружается!!!
Похоже что проблема в opendislog (извините за выводы).

P.S. про нормальную работу без opendislog я писал в самом начале
Ответить с цитированием
  #15  
Старый 02.11.2013, 11:51
Аватар для Alegun
Alegun Alegun вне форума
LMD-DML
 
Регистрация: 12.07.2009
Адрес: Богородское
Сообщения: 3,025
Версия Delphi: D7E
Репутация: 1834
По умолчанию

Вы думаете что я издеваюсь над неофитом? Вот смотрите сами, у меня это работает без ошибок
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 02:31.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter