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

Вниз

dll   Найти похожие ветки 

 
Sw   (2014-08-28 13:15) [0]

Помогите пожалуйста!
в 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


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

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

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

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


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

если после этого кода:
 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?
да


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

извиняюсь..

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

iq.Open;


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

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


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

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


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

доступа к исходнику  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;


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

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

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


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


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

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


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


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

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

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


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


> а когда находит - все 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 16:14) [11]


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

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


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

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

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

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

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

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

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


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

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

мне вот что еще непонятно..
убираю синхронайз...посылаю 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 не словит из другого потока?


 
icWasya ©   (2014-09-17 09:16) [14]

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


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


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

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


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

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


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


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

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

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

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



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

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

Наверх




Память: 0.52 MB
Время: 0.005 c
4-1273238553
Pashka.cool
2010-05-07 17:22
2016.04.10
BlueTooth не удаётся обуздать уже несколькими способами.


2-1409217347
Sw
2014-08-28 13:15
2016.04.10
dll


15-1438291801
Юрий
2015-07-31 00:30
2016.04.10
С днем рождения ! 31 июля 2015 пятница


15-1438194003
Дмитрий С
2015-07-29 21:20
2016.04.10
Оптимизация сетки бронирования автопарка.


1-1337273859
Ivan
2012-05-17 20:57
2016.04.10
ГРАФИК ТРАКТРИСЫ