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

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

TBlobField и приведение типов [D7, IB6.x]


ChaoX ©   (2007-08-19 06:54:00) 

Нужно кинуть в конструктор TBlobStream параметр типа TBlobField, и логично, что я пытаюсь сделать так:
stream := TBlobStream.Create((IBTable1.FieldByName('NH_MAP') as TBlobField), bmRead);
Ан нет! Говорит, что "Invalid typecast".
Я попробовал тогда узнать, какого на самом деле типа поле вызовом ClassName и сильно удивился узнав, что это... TBlobField!
Тогда я сделал проверку на is:
if IBTable1.FieldByName('NH_MAP') is TBlobField then
begin
 ShowMessage('1');
end;

И она сработала!
Однако

if IBTable1.FieldByName('NH_MAP') is TBlobField then
begin
 stream := TBlobStream.Create((IBTable1.FieldByName('NH_MAP') as TBlobField), bmRead);
end;


Опять выдаёт ошибку...

Может хоть кто-нибудь объяснит мне, что происходит?
Жду вашей помощи


kaif   (2007-08-21 15:51:00) [1]

Кстати, если тебе интересно, конечно, разобраться до конца - обрати внимание на то, что классы TIBBlobStream и TIBDSBlobStream не являются даже потомками класса TBlobStream, а происходят от базового класса TStream непосредственно.


kaif   (2007-08-21 15:46:00) [2]

Так что это вовсе не глюк, а неверная работа с блобстримом, когщда используешь нативную клиентскую библиотеку компонентов доступа типа IBX.

И если у тебя в usesмодуля в результате осталась ссылка на DBTables, желательно ее все же убрать оттуда, если не хочешь при компиляции присобачивать к своему экзешнику всю поддержку BDE, которавя в данном случае тебе вовсе не требуется.


kaif   (2007-08-21 15:42:00) [3]

Так что если хочешь вызывать конструктор блобстhима, то ливо вызывай метод датасета, как рекомендует Борланд, либо используй нужный конструктор, предусмотренный производителем.
Например  в Help по IBX есть такой пример:

procedure TForm1.Button1Click(Sender: TObject);

var
 Stream1, Stream2 : TIBBlobStream;
begin
 Stream1 := TIBBlobStream.Create(IBTable1Notes);
 try
   Stream1.Mode = bmRead;
   IBTable2.Edit;
   { here’s a different way to create a blob stream }
   { note that with this one, we don’t need a try.. finally clause }
   { because we are not responsible for freeing the stream }
   Stream2 := IBTable2.CreateBlobStream(IBTable2.FieldByName('Remarks'), bmReadWrite);
   Stream2.CopyFrom(Stream1, Stream1.Size);

   IBTable2.Post;
 finally
   Stream1.Free;
 end;
end;


Настоящая же причина того, что класс TBlobStream вообще нельзя так использовать, как я подозреваю, состоит в том, что этот класс определен в модуле DBTables VCL, который обслуживает исключительно BDE-соместимые классы и с нативными компонентами библиотеки InterBase Exepress (IBX) не должен использоваться в принципе.


kaif   (2007-08-21 15:25:00) [4]

Тьфу (опечатался), то есть TIBDSBlobStream


kaif   (2007-08-21 15:24:00) [5]

В Help касательно конструктора TBlobStream.Create написано вот эта рекомендация:

Different types of dataset use different classes of BLOB streams. It is usually a better idea to call the dataset’s CreateBlobStream method than to call the BLOB stream constructor. - различные типы датасетов используют различные классы блобстримов. Обычно предпочтительнее вызывать метод CreateBlobStream, реализованный конкретным датасетом, чем вызывать этот вот конструктор блобстрима.

Возможно у тебя неверный typecast вовсе не в классе поля, а в классе самого стрима. Попробуй выяснить classname стрима, порожденного методом TDataset.CreateBlobStream.

Например у меня вот такой код:

procedure TForm1.Button1Click(Sender: TObject);
begin
 ShowMessage(IBQuery1.CreateBlobStream(IBQuery1.FieldByName('некое поле'), bmRead).ClassName)
end;


вернул имя класса - TIBDSBlobField


ChaoX   (2007-08-19 17:34:00) [6]


> Desdechado ©   (19.08.07 17:18) [5]

Большое спасибо.

Кстати, мне просто интересно, из-за чего возникал тот глюк?


Desdechado   (2007-08-19 17:18:00) [7]

TDataset.CreateBlobStream


Плохиш   (2007-08-19 17:15:00) [8]


> Ну и что?

Ничего, продолжайте.


ChaoX   (2007-08-19 17:03:00) [9]


> Класс TBlobField имеет метод SaveToStream...

Ну и что?
Проблемы возникают как раз на приведении к типу TBlobField.
Я не могу получить TBlobField и, соответственно, вызывать его методы.


Плохиш   (2007-08-19 16:41:00) [10]


> ChaoX ©   (19.08.07 06:54)  

Класс TBlobField имеет метод SaveToStream...


Reindeer Moss Eater   (2007-08-19 11:41:00) [11]

Я попробовал тогда узнать, какого на самом деле типа поле вызовом ClassName и сильно удивился узнав, что это... TBlobField!

А нет никакой разницы какого типа поле.
Так как FieldByName все равно возвращает тип TField.


Наверх

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