Форум: "Начинающим";
Текущий архив: 2016.04.10;
Скачать: [xml.tar.bz2];
Вниз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;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.002 c