Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

dll [D7, XP]


Sw ©   (2014-08-28 13:15:00) 

Помогите пожалуйста!
в dll:

 IBDB:=TIBDatabase.Create(Application);
 IBDB.Params.Clear;
 IBDB.LoginPrompt:=False;
 IBDB.DatabaseName:='D:\Test\DB.fdb';
 IBDB.Params.Add('user_name=SYSDBA');
 IBDB.Params.Add('password=masterkey');
 IBDB.Params.Add('lc_ctype=win1251');
 IBDB.Connected:=true;

 IBTR:=TIBTransaction.Create(Application);
 IBTR.DefaultDatabase:=IBDB;

 if IBDB.Connected then  ShowMessage('e');


из основной программы вызываю dll-ky, все нормально отрабатывает, ошибок не выдает, появляется сообщение 'e', т.е. я понимаю, что соединение с базой установлено.
Дальше если в исходный код добавить:

 iq:=TIBQuery.Create(Application);
 iq.Database:=IBDB;
 iq.Transaction:=IBTR;
 iq.SQL.Text:= 'select id from cs';
 iq.Open;


ругается на память ...инструкция по адресу ...обратилась к памяти....Runtime error


ВладОшин   (2014-09-17 11:15:00) [1]


> можно применять некие переменные

желательно простые, типа int/byte и т.п.

потом, у тебя в потоке
fm.IBDB:=TIBDatabase.Create(Application);
т.е. обращение к другому потоку, vcl
в принципе не страшно, но не знай как работает TIBDatabase (не юзал IB)
возможно, следует создать TIBDatabase чисто в потоке, а в основном потоке не создавать, а приравнять к созданному. Поток тогда не надо уничтожать, естественно.
т.е. поток создает, соединяется и предоставляет свой объект другим
из плюсов - можно создать еще и еще потоки-соединяльщики и каждый работает паралльльно (надо только следить за ненужными и настройками БД на кол-во с одного места коннектов:). Тут можно какую функцию написать, возвращающую первый свободный коннект, или создавая новый. В общем фантазий - полет)

тоже не знаю насколько это правильно(пусть поправит кто), но работает пока


ВладОшин   (2014-09-17 11:01:00) [2]


> убираю синхронайз...посылаю Message и основной поток в случае
> отсутствия соединения с базой должен уничтожить поток-соединяльщик.
> .Вы думаете так сработает?

да
но не знаю насколько правильно. Но сам так делал :)


> А такая конструкция не работает:если нет соединения с базой,
>  тогда F:=false; и на кнопку
>

боюсь, не понял
но можно применять некие переменные, при условии, что они будут писаться  только одним каким-либо потоком. Остальные потоки только читать ее.
опять же - не знаю насколько правильно. Но сам так делал :)


icWasya   (2014-09-17 09:16:00) [3]

вместо ConnectThread.Execute;надо ConnectThread.Resume;


Sw   (2014-09-17 08:39:00) [4]

спасибо за помощь в направлении движения, это мне конечно надо поизучать...
> сейчас второй поток работает в контексте основного потока
понятно...сложилась наконец-то картинка...не доходило

мне вот что еще непонятно..
убираю синхронайз...посылаю Message и основной поток в случае отсутствия соединения с базой должен уничтожить поток-соединяльщик..Вы думаете так сработает? А такая конструкция не работает:если нет соединения с базой, тогда F:=false; и на кнопку

 ConnectThread:=TConnectThread.Create(true);
 ConnectThread.Priority:=tpNormal;
 ConnectThread.Execute;
 if not F then
  begin
    ConnectThread.FreeOnTerminate:=true;
    ConnectThread.Terminate;
    Exit;
  end
 else...

не сработает, потому что F не словит из другого потока?


ВладОшин   (2014-09-16 16:29:00) [5]

сейчас второй поток работает в контексте основного потока

а я имею ввиду аля так

procedure TConnectThread.ConnectLO; //подключение к базе
....
fm.IBDB.Open;
----
тут сообщение(Message или ThreadMessage) об успешном открытии
----
except
on E: Exception do
 begin
тут сообщение(Message или ThreadMessage) об ошибке
===========

Tfm
...
procedure bla-bla ; message WM_ТВОЯ_МЕССАГА

=====
идеология:

TConnectThread запускается без синхронайза
TConnectThread начинает соединятся и отправляет мессагу по факту да/нет
основной поток ловит мессагу и решает что делать


ВладОшин   (2014-09-16 16:14:00) [6]


> procedure TConnectThread.Execute;
> begin
>  Synchronize(ConnectLO);
> end;

и зачем тогда поток?


Sw   (2014-09-16 12:59:00) [7]


> а когда находит - все ok?

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


 TConnectThread = class(TThread)
   private
 protected
   procedure Execute; override;
   procedure ConnectLO;
 end;

var
 ConnectThread: TConnectThread;
 F:boolean;

procedure TConnectThread.ConnectLO; //подключение к базе
var n,n1:IXMLNode;
   SL: TStringList;
   DS,Path_DB:string;
begin
try
 F:=false;
 fm.XMLDocument1.FileName:='D:\test.xml';
 fm.XMLDocument1.Active:=true;
 n:=fm.XMLDocument1.ChildNodes.FindNode('Config'); //Имя секции
 n1:=n.ChildNodes.FindNode('DB'); //Имя вложенной секции

 SL:=TStringList.Create;
 SL.Delimiter := ';';
 SL.DelimitedText := n1.XML;
 DS := SL.Values['DataSource'];
 Path_DB:=DS+':D:\test.fdb';

 fm.IBDB:=TIBDatabase.Create(Application);
 fm.IBDB.Params.Clear;
 fm.IBDB.LoginPrompt:=False;
 fm.IBDB.DatabaseName:=Path_DB;
 fm.IBDB.Params.Add('user_name=SYSDBA');
 fm.IBDB.Params.Add('password=masterkey');
 fm.IBDB.Params.Add('lc_ctype=win1251');
 fm.IBDB.Connected:=false;
 fm.IBDB.Close;
 fm.IBDB.Open;

except
 on E: Exception do
  begin Application.MessageBox('Не удалось создать подключение к базе данных.','Сообщение',MB_OK+MB_ICONERROR);
    SL.Free;
    fm.IBDB.Free;
    ConnectThread.FreeOnTerminate:=true;
    ConnectThread.Terminate;
    Exit;
  end;
end;
 SL.Free;
 F:=true;
end;

procedure TConnectThread.Execute;
begin
 Synchronize(ConnectLO);
end;

//******************************************************************************
procedure Tfm.BtnImportClick(Sender: TObject); //Загрузка данных из БД
begin
//подключение к базе
 ConnectThread:=TConnectThread.Create(true);
 ConnectThread.Priority:=tpNormal;
 ConnectThread.Execute;
 if not F then begin Exit;end else

try
 IBTR:=TIBTransaction.Create(Application);
 IBTR.DefaultDatabase:=IBDB;
 if not IBTR.InTransaction then IBTR.StartTransaction;

 iqTRS:=TIBQuery.Create(Application);...........


ВладОшин   (2014-09-16 09:18:00) [8]


> сли не находит базу по сети.

а когда находит - все ok?
т.е. а было так, что нашел, и все при этом было все ok?

Поток может помочь.
Не знаю правильно-нет, но как то делал, что поток соединялся, и возвращал мессагой указатель на соединение. Поток-пользователь соответственно ждал мессагу сколько то времени, если дожидался, то приводил полученный указатель к нужному и юзал, а если нет, то завершение программы
Из минусов - поток-соединяльщик потом все время работает.
( Ну там он у меня на самом деле пулом был, там несколько соединений было с постоянными запросами вида select "какая_нибудь_ерунда" по ним, что бы ОСь/сервер не отключали долго не используемое соединение )


Sw   (2014-09-16 08:24:00) [9]

вот думаю, если реализовать подключение в отдельном потоке и если not IBDB.Connected тогда убить процесс...и один хрен...все-тоже самое...я так понимаю,TIBDatabase не освобождает ресурсы, ждет ответа сервера..не закрывает socket...Может кто-нить подскажет, как бы корректно обработать выход из dll, если нет соединения с базой..


Sw   (2014-09-02 07:33:00) [10]

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

try
...
IBDB.Open;
except
 on E: Exception do
  begin Application.MessageBox('Не удалось создать подключение к базе данных.     ','Сообщение',MB_OK+MB_ICONERROR);
    IBDB.Free;
    Exit;
  end;
end;


интересно, что dll-ка работает, ее можно закрыть без проблем ...а главное приложение сразу виснет...
Может чем поможете? Что с этим делать?


Sw   (2014-08-29 11:01:00) [11]

доступа к исходнику  exe у меня нет..
заработало вот так:

 IBDB:=TIBDatabase.Create(Application);
 IBDB.Params.Clear;
 IBDB.LoginPrompt:=False;
 IBDB.DatabaseName:='localhost:D:\Test\DB.fdb';
 IBDB.Params.Add('user_name=SYSDBA');
 IBDB.Params.Add('password=masterkey');
 IBDB.Params.Add('lc_ctype=win1251');
 IBDB.Connected:=false;

 IBDB.Close;
 IBDB.Open;

 IBTR:=TIBTransaction.Create(Application);
 IBTR.DefaultDatabase:=IBDB;
 if not IBTR.InTransaction then IBTR.StartTransaction;

 iq:=TIBQuery.Create(Application);
 iq.Database:=IBDB;
 iq.Transaction:=IBTR;
 iq.Close;
 iq.SQL.Text:='select id from cs';
 iq.Open;
 iq.First;

 if IBTR.InTransaction then iq.Transaction.Commit;
 
 IBDB.Close;
 iqs.Free;
 IBTR.Free;
 IBDB.Free;


junglecat   (2014-08-29 09:58:00) [12]

Зачем Application в качестве владельца? Лучше создавать при загрузке DLL (в DLL_PROCESS_ATTACH) удалять при выгрузке.
И exe и dll собраны с runtime packages?


junglecat   (2014-08-29 09:46:00) [13]

а сам запрос 'select id from cs' работает?


Sw   (2014-08-29 05:16:00) [14]

извиняюсь..

> на какой строке?

iq.Open;


Sw   (2014-08-29 05:10:00) [15]

если после этого кода:
 IBTR:=TIBTransaction.Create(Application);
 IBTR.DefaultDatabase:=IBDB;
 if IBDB.Connected then  ShowMessage('e');

добавить:
iq:=TIBQuery.Create(Application);
iq.Database:=IBDB;
iq.Transaction:=IBTR;
iq.SQL.Text:= 'select id from cs';
iq.Open;

тогда возникнет ошибка
> исходный код dll?
да


junglecat   (2014-08-28 13:47:00) [16]

на какой строке?

> в исходный код добавить

исходный код dll?


Наверх

Титульная страница Поиск, карта сайта Написать письмо