Компоненты SQLdb в консольном приложении

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Ответить
wwswowsogon
постоялец
Сообщения: 157
Зарегистрирован: 23.12.2008 19:41:37

Компоненты SQLdb в консольном приложении

Сообщение wwswowsogon »

Всем доброго времени суток!

Решил сделать консольное приложение, использующее компоненты SQLdb.

И внезапно столкнулся с проблемами, возможно, связанными с плохим пониманием работы компонентного подхода Lazarus. Есть простой код подключения к БД, примерно следующий:

Код: Выделить всё


function DBConnect(): Boolean;
var
  db_path, db_username, db_password: String;
begin

  Result := false;

  db_path := 'data\db\dbmain.fdb';

  db_username := 'SYSDBA';
  db_password := 'masterkey';

  IBConnection1.DatabaseName := db_path;

  IBconnection1.UserName := db_username;
  IBconnection1.Password := db_password;

  ...

  try
    SQLTransaction1.Active := true;

    Result := true;

  except
    WriteLn('Ошибка подключения к БД!');
    ReadLn();
  end;
end;



Он вызывает RTE, по-видимому, на строчке

Код: Выделить всё

IBConnection1.DatabaseName := db_path;


Тот же RTE, типа Access Violation или что-то ещё более непонятное, возникает, если создать оконное приложение с тем же кодом, без использования компонентов SQLdb, размещённых на форме. В обоих случаях я прописывал IBConnection1, SQLQuery1 и т. д. в виде переменных, глобальных или внутри функции.

Если же разместить компоненты на форме, при чем они прописываются автоматом в экземпляре класса формы, то всё работает нормально.

Чего я не понимаю?
Аватара пользователя
Tango
постоялец
Сообщения: 162
Зарегистрирован: 31.05.2012 17:07:30

Сообщение Tango »

А IBConnection1 создано? По коду вижу что, нет.
IBConnection1:=TIBConnection.Create(nil); забыл?
S_Gur
постоялец
Сообщения: 136
Зарегистрирован: 30.12.2018 21:17:42

Сообщение S_Gur »

Консольные приложения прекрасно работают с датамодулями. Разместите на датамодуле свои компоненты
wwswowsogon
постоялец
Сообщения: 157
Зарегистрирован: 23.12.2008 19:41:37

Сообщение wwswowsogon »

Tango писал(а):А IBConnection1 создано? По коду вижу что, нет.
IBConnection1:=TIBConnection.Create(nil); забыл?


Не то что забыл, а даже и не знал. В случае оконного приложения так не делал никогда. Но по сути проблемы похоже, что причина именно в этом. Видимо, в обычном режиме этот объект создается как-то автоматически.

Спасибо за ответы. В общем-то, я уже сделал то, что требовалось, с помощью обычного окна. Но - учту на будущее. ;)
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

wwswowsogon писал(а):Не то что забыл, а даже и не знал.

На всякий случай. Все компоненты (вероятность близка к 100%) являются штуками динамическими, т.е. перед их использованием им непременно надо выделить память, аналогично указателям. Компоненты - тоже указатели, только очень сложные и внутри них есть как ещё какие-нибудь указатели, так и статические элементы. Чтобы программист, который пользует компонент, не перебирал все по очереди элементы, выделяя для них память, у компонента есть метод "Create()", внутри которого как раз память для всего на свете и выделяется. GUI-приложения (оконные) чем хороши (одновременно и плохи) - у них практически все методы "Create()" упрятаны внутрь компонента "Application", для которого Create() Lazarus подставляет автоматически. Application перебирает всю иерархию своих компонентов, вызывая у каждого относящийся к ним Create().
Если Вы создаёте консольное приложение, в данном случае с компонентами базы данных не используя DataModule, который бы сам Вам всё создал, то вызовом Create() для все ДБ-компонентов должны заниматься Вы сами, ручками. В этом нет ничего страшного, просто помните, что все компоненты - указатели и кто-то должен им вызвать Create() - если не Lazaus, то Вы сами... ;-)
wwswowsogon
постоялец
Сообщения: 157
Зарегистрирован: 23.12.2008 19:41:37

Сообщение wwswowsogon »

Vadim писал(а):
wwswowsogon писал(а):Не то что забыл, а даже и не знал.

На всякий случай. Все компоненты (вероятность близка к 100%) являются штуками динамическими, т.е. перед их использованием им непременно надо выделить память, аналогично указателям. Компоненты - тоже указатели, только очень сложные и внутри них есть как ещё какие-нибудь указатели, так и статические элементы. Чтобы программист, который пользует компонент, не перебирал все по очереди элементы, выделяя для них память, у компонента есть метод "Create()", внутри которого как раз память для всего на свете и выделяется. GUI-приложения (оконные) чем хороши (одновременно и плохи) - у них практически все методы "Create()" упрятаны внутрь компонента "Application", для которого Create() Lazarus подставляет автоматически. Application перебирает всю иерархию своих компонентов, вызывая у каждого относящийся к ним Create().
Если Вы создаёте консольное приложение, в данном случае с компонентами базы данных не используя DataModule, который бы сам Вам всё создал, то вызовом Create() для все ДБ-компонентов должны заниматься Вы сами, ручками. В этом нет ничего страшного, просто помните, что все компоненты - указатели и кто-то должен им вызвать Create() - если не Lazaus, то Вы сами... ;-)


Спасибо за информацию, полезно. Когда-то работал с GLScene, и там объекты динамически создаются сходным образом, что я и использовал неоднократно. В данном случае да, сыграл роль недостаточный опыт создания объектов вне DesignTime'a ;)
Ответить