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

Поиск:

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


Новичок



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

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



Всем доброго времени суток!
Опишу задачу поподробней:
Есть панель с кнопками, создающимися динамически,
какдая кнопка должна запускать форму из Dll, (не модально), т.е. сколько кнопок - столько и форм из Dll-ок можно запустить...
Т.к. кнопки динамические - то OnClick один:
Код
procedure TMainF.BtnClick(Sender:TObject);
.......
....
lib_name:=f.ReadString(List.Strings[(SenderasTBitBtn).Tag],'lib','');
//глобальная премем. имя библиотеки (Dll)
lib_proc:=f.ReadString(List.Strings[(SenderasTBitBtn).Tag],'startpoint',''); //глобальная ,процедура вызова формы из Dll
hh[(SenderasTBitBtn).Tag]:=loadLibrary(pChar(lib_name));
Thread_num:=(Sender as TBitBtn).Tag;
//определяю номер потока
Z_ST[(SenderasTBitBtn).Tag]:=TZthread.Create(false);
//создаю поток с номером...
......
end;

да, вещё вот такой кусочек :
Код
type
  TZThread = class (TThread)
  protected
  procedure Execute; override;
end;

Массивы:
 
Код
Z_ST: array of TZThread;
       hh: array of THandle;

И обработчик Execute:
Код

procedure TZThread.Execute;
var MyHandl:THandle;
    Go:procedure(DbName,UserName,Pasword:string);
begin
  self.FreeOnTerminate:=true;
  MyHandl:= FindWindow(Nil, '.....');
  if MyHandl<>0 then SetForegroundWindow(MyHandl) else begin
     if hh[Thread_num]<>0 then begin      @GO:=GetProcAddress(hh[Thread_num],pChar(lib_proc));
       GO(DN,UN,PS);
     end else messagebox(Application.Handle,'Отсутствует модуль dll!','Ошибка.',MB_OK+MB_ICONERROR);
.............
  end;
end;

В результате получается вот такоя картина:
если я к примеру открою 3 формы(по 1й из 3х Dll), то, закрывая последнюю, все ок, но закрывая  две  предыдущие - они закрываются и компилятор говорит - "Invalid pointer operation".(((
Получается когда закрывается форма - управление должно передаваться в процеддуру Execute, где-то вот сюда:
Код
GO(DN,UN,PS);

и там должно быть что-то вроде 
Код
Z_ST[...]:=Nil;
и
FreeLibrary(hh[...]);

Но не идет тута ни чего, когда закрываб те 2 не последние формы ((((.
Как быть и что делать, где я не прав???
Подскажите плиз, я оч запутался!
PM MAIL   Вверх
ama_kid
Дата 28.3.2007, 07:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


АСУТП-кодер
***


Профиль
Группа: Комодератор
Сообщений: 1460
Регистрация: 5.3.2007
Где: Москва

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



приложил бы код к посту, а то слишком много пропусков и многоточий, без поллитра и не разберешься, что моделировать надо...
Цитата(appleVin @  27.3.2007,  23:13 Найти цитируемый пост)
сли я к примеру открою 3 формы(по 1й из 3х Dll), то, закрывая последнюю, все ок, но закрывая  две  предыдущие - они закрываются и компилятор говорит - "Invalid pointer operation".(((

Это не компилятор говорит (компилятор сказал все что о думает, еще на этапе компиляции), это AV... Есть подозрение, что ты где-то пользуешься расшаренными ресурсами библиотеки, соответственно при открытии последней формы они переинициализируются на неё, забирая у предыдущих...


--------------------
самурай без меча подобен самураю с мечом, но только без меча 
PM MAIL   Вверх
appleVin
  Дата 28.3.2007, 09:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата

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

Да, мне кажется так и есть smile , но вопрос в том, как быть в этом случае smile 
PM MAIL   Вверх
MetalFan
Дата 28.3.2007, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



имхо лучше отказаться от использования  в dll наследников TComponent и форм в частности.


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


Новичок



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

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



Цитата

имхо лучше отказаться от использования  в dll наследников TComponent и форм в частности.

 Да я бы рад, но задача у меня такая...
PM MAIL   Вверх
ama_kid
Дата 28.3.2007, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


АСУТП-кодер
***


Профиль
Группа: Комодератор
Сообщений: 1460
Регистрация: 5.3.2007
Где: Москва

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



appleVin
Ну приведешь ты наконец коды или нет?  smile  Если код большой или тайный - убери лишнее или смоделируй на тестовом проекте и его выложи... А то на пальцах гадать как-то больно сложно... По тому, что ты привел, я еще раз повторю, сложно судить об ошибке и смотреть в правильную сторону... Может там ошибка-то плёвая, а мы тут рассуждать щас начнём...  smile 


--------------------
самурай без меча подобен самураю с мечом, но только без меча 
PM MAIL   Вверх
appleVin
Дата 28.3.2007, 13:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Дык без вопросов, ща весь Юнит и закину smile 
Токо там много лишнего и не нужного, короче чур громко не жжать smile

Добавлено через 6 минут и 9 секунд
Код

type
  TZThread = class (TThread)
  protected
  procedure Execute; override;
end;

type

  TMainF = class(TForm)
    Panel1: TPanel;
    BitBtn1: TBitBtn;
    Panel2: TPanel;
    Timer1: TTimer;
    pFIBDatabase1: TpFIBDatabase;
    BitBtn4: TBitBtn;
    pFIBTransaction1: TpFIBTransaction;
    pFIBTransaction2: TpFIBTransaction;
    procedure FormActivate(Sender: TObject);
    procedure BitBtn5Click(Sender: TObject);
    procedure Panel1Click(Sender: TObject);
    procedure BitBtn2Click(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    procedure BitBtn3Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure BitBtn4Click(Sender: TObject);
    procedure BitBtn8Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure CSocketRead(Sender: TObject; Socket: TCustomWinSocket);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    procedure BtnClick(Sender:TObject);

 private
    { Private declarations }
  public
    { Public declarations }

end;

var
  MainF: TMainF;
  f:TIniFile;
  b:array of TBitBtn;
  DN,UN,PS,sc,ss:string;
  jList:integer;
  Z_ST: TZThread;   Z_S:Array of TThread;
  InExp_ST: TInExpThread;
  Evs: TEvents;      hh:Array of THandle;
  //{h,}MyHandl:THandle;
  HandlList:TStringList;
  Thread_num: Integer;       Go:procedure(DbName,UserName,Pasword:string);

implementation


uses Unit2;
{$R *.dfm}

procedure TZThread.Execute;
var h,MyHandl:THandle;
    Go:procedure(DbName,UserName,Pasword:string);
      i:Integer;
begin
  {****************************************************************************}
 //Z_ST.FreeOnTerminate:=true;
// self.FreeOnTerminate:=true;
  //MyHandl:= FindWindow(Nil, pChar('sc'));
  //if MyHandl<>0 then SetForegroundWindow(MyHandl) else begin
     //h:=LoadLibrary(pChar(sc));
     if hh[Thread_num]<>0 then begin
        @GO:=GetProcAddress(hh[Thread_num],pChar(ss));
        GO(DN,UN,PS);

     end else messagebox(Application.Handle,'Отсутствует модуль'{+StrPCopy(APchar,f.ReadString(List.Strings[(Sender as TBitBtn).Tag],'lib',''))}+'!','Ошибка.',MB_OK+MB_ICONERROR);
    Z_S[Thread_num]:= nil;
 //  end;
  {****************************************************************************}
end;
procedure TMainF.BtnClick(Sender:TObject);
var
List:TStringList;
i:integer;
APchar:array[0..254] of char;
AP2char:array[0..254] of char;
label 1;
begin
 sc:='';
 ss:='';
 f:=TIniFile.Create(ExtractFileDir(Application.ExeName)+'\launcher.ini');
List := TStringList.Create;
List.Clear;
f.ReadSections(List);
SetLength(b,List.Count);
{-------}
  pFIBDatabase1.Connected:=false;
  pFIBDatabase1.DBName:= f.ReadString(List.Strings[(Sender as TBitBtn).Tag],'DbName','Нет заданного сервера');
  if f.ReadBool(List.Strings[(Sender as TBitBtn).Tag],'Autologin',true) then
   begin
     pFIBDatabase1.ConnectParams.UserName:=f.ReadString(List.Strings[(Sender as TBitBtn).Tag],'USER','');
     pFIBDatabase1.ConnectParams.Password:=f.ReadString(List.Strings[(Sender as TBitBtn).Tag],'PASS','');
    try pFIBDatabase1.Connected:=true;
     except Application.CreateForm(TFLogin, FLogin);
      flogin.ShowModal;
      flogin.Free;
    end;
   end
  else
   begin
    Application.CreateForm(TFLogin, FLogin);
    flogin.ShowModal;
    flogin.Free;
   end;
  if pFIBDatabase1.Connected=true then
   begin
    DN:=pFIBDatabase1.DBName;
    UN:=pFIBDatabase1.ConnectParams.UserName;
    PS:=pFIBDatabase1.ConnectParams.Password;
   end
   else begin flogin.Close; {application.Terminate;} goto 1;  end;
     sc:=f.ReadString(List.Strings[(Sender as TBitBtn).Tag],'lib','');
     ss:=f.ReadString(List.Strings[(Sender as TBitBtn).Tag],'STARTPOINT','');
     Thread_num:=((Sender as TBitBtn).Tag)+1;
     hh[Thread_num]:=loadLibrary(pChar(sc));
     Z_S[Thread_num]:= TZThread.Create(false);
     Z_S[Thread_num].FreeOnTerminate:=true;
List.Free;
f.Free;
Evs.Free;

1:

end;

procedure TMainF.FormActivate(Sender: TObject);
var
List:TStringList;
n,i:integer;
begin
f:=TIniFile.Create(ExtractFileDir(Application.ExeName)+'\launcher.ini');
List := TStringList.Create;
List.Clear;
f.ReadSections(List);
SetLength(b,List.Count);
SetLength(Z_S,List.Count);
SetLength(hh,List.Count);
 for i:=0 to List.Count - 1 do
  begin
   b[i] := TBitbtn.Create(panel1);
   b[i].Parent := Panel1;
   b[i].Caption := f.ReadString(List.Strings[i],'caption','#ERROR#');
   if i=0 then
    begin
    b[i].Left:= f.ReadInteger(List.Strings[i],'left',0);
    b[i].Top:= f.ReadInteger(List.Strings[i],'top',0);
    end
   else
   begin
    b[i].Left := b[i-1].Left+b[i-1].Width+f.ReadInteger(List.Strings[i],'left',0);
    b[i].Top:=b[i-1].Top;
   end;
   b[i].Width := f.ReadInteger(List.Strings[i],'Width',0);

 if (Panel1.Width-b[i].Left) < b[i].Width then
  begin

   b[i].Top:=Panel1.Height;
   MAinF.ClientHeight:=MainF.ClientHeight+b[i].Height+3;
   b[i].Left:=5;
  end
   else
   b[i].Tag :=i;
   b[i].Glyph.LoadFromFile(f.ReadString(list.Strings[i],'glyph',''));
   b[i].OnClick:= BtnClick;
 end;
jList:= list.Count;
List.Free;
f.Free;
Evs.Free;
end;
// выход из программы
procedure TMainF.BitBtn1Click(Sender: TObject);
var i:Integer;
begin

  for I := 0 to List.Count -1 do
    begin
     if (not (z_s[i] = nil)) then
     begin
       freeLibrary(hh[i]);
       z_s[i]:= nil;
     end;
    end;
      timer1.Enabled:=true;
end;
procedure TMainF.Timer1Timer(Sender: TObject);
begin
Application.Terminate;
end;


Вот сообственно нужный кусочек
PM MAIL   Вверх
MetalFan
Дата 28.3.2007, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



ты бы лучше закинул тестовое приложение, чтоб скомпилить, запустить - и воооотона ошибочка то!


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


АСУТП-кодер
***


Профиль
Группа: Комодератор
Сообщений: 1460
Регистрация: 5.3.2007
Где: Москва

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



appleVin
Давай я тебе поясню, как надо выкладывать проблему, по шагам:
1) Делаешь резервную копию своего проекта...
2) Убираешь потихоньку все компоненты и методы, которые не влияют на ошибочность ситуации (к примеру, у меня нет компонента TpFIBDatabase и он мне не нужен - все места, где оттуда считываются данные - заменяешь на константные присваивания)...
3) Проверяешь, что все компилируется и собирается... и ошибка никуда не делась... 
4) Еще раз убеждаешься, что у тебя не используется в обрезанном проекте никакие модули, кроме системных, входящих в штатную поставку дельфей...
5) ВСЕ файлы (исключая скомпиленные и временные, но обязательно включая используемые библиотеки и их исходники, если есть, и файлы конфигурации) помещаешь в архив и прикрепляешь к посту. Если размер превысил разрешенные 120 кб - используй внешние хранилища (типа webfile).
6) Человек, имеющий желание тебе помочь, скачивает архив, запускает у себя, получает наглядную визуализацию ошибки и начинает тупо жать F7, F8 до получения некорректной ситуации и выцарапывания неверной предпосылки путем нехитрого анализа...

P.S. Если честно, я просто даже не знаю, что делать с приведенным тобой кодом - чтобы его внедрить, мне надо переименовать форму в такую же как у тебя, предварительно разместить все аналогичные компоненты как у тебя, создать все обработчики и только потом я смогу сделать replace текста своего модуля на твой текст. Уж больно лениво... К тому же я не знаю внешних связей этого модуля - интерфейсный раздел uses куда-то обрезался, а внутренний - неинформативный...
P.P.S. Ввиду того, что как ты говорил, ошибка возникает при закрытии формы из библиотеки, то не совсем понятно, зачем ты привел код твоего приложения, а не библиотеки... Я как-то не научился в детстве телепатическим способностям, чтобы такие вещи угадывать...  smile
P.P.P.S. Ну и мелкие замечания по не совсем корректной структуре кода - а) и поток, и главная форма используют общие переменные, б) поток сбрасывает переменные, устанавливаемые в основном процессе. Поток на то и отдельная структура, что работает независимо от основного процесса. По хорошему - я бы завел все необходимые для потока параметры в наследуемый класс потока, при создании потока их инициализировал и в Execute работал бы с ними. По завершению потока они сами бы и уничтожались вместе с объектом потока...


--------------------
самурай без меча подобен самураю с мечом, но только без меча 
PM MAIL   Вверх
appleVin
Дата 30.3.2007, 08:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



ama_kid Спасибо за беспокоиство, тут разобрались с горем пополам, а за советы отдельное спасибо smile , я новичок совсем ещё - так что учту на будущее!  smile 
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.0539 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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