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

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

GUID + Variant = Love ? [D5, Win2k]


Alkid ©   (2006-08-02 10:32:00) 

Вопрос - как правильно обращаться с GUID`ами, когда их надо сохранять в Variant`e? Мне пока пришло в голову в строки их переводить, но это как-то некрасиво. Речиь идёт о Delphi 5.


Jeer   (2006-08-02 12:30:00) [1]

http://www.ibase.ru/devinfo/test2.htm


Ega23   (2006-08-02 12:21:00) [2]


> Более того, использовать GUID в чистом виде в ключевых полях
> нерационально, т.к. приращение идет с конца, что плохо для
> индексации.
> Для этого используют "перевернутый" GUID, для FB есть UDF.
>


Возможно. Но надо.
А какое-такое приращение?


Сергей М.   (2006-08-02 12:11:00) [3]


> Alkid ©   (02.08.06 12:00) [15]


Ну напиши свою функцию копирования .. Что , на VarCopy или прямом присваивании разве свет клином сошелся ?

На худой конец храни в варианте не сам GUID, а указатель на него .. Или храни как varArray ..


Lamer@fools.ua   (2006-08-02 12:04:00) [4]

>> Jeer ©   (02.08.06 11:24) [7]

TCustomVariantType появился в D6, если не ошибаюсь.

По сабджу
Я бы предложил один из таких вариантов:
1. TVarData(V).VType := varAny & TVarData(V).VAny (нужно будет вручную выделять и освобождать память).
2. TVarData(V).VBytes (нужно будет вручную устанавливать TVarData(V).VType := varEmptyпосле окончания использования).


Alkid   (2006-08-02 12:00:00) [5]


 TVarData = packed record
   VType: Word;
   Reserved1, Reserved2, Reserved3: Word;
   case Integer of
     varSmallint: (VSmallint: Smallint);
     varInteger:  (VInteger: Integer);
     varSingle:   (VSingle: Single);
     varDouble:   (VDouble: Double);
     varCurrency: (VCurrency: Currency);
     varDate:     (VDate: Double);
     varOleStr:   (VOleStr: PWideChar);
     varDispatch: (VDispatch: Pointer);
     varError:    (VError: Longword);
     varBoolean:  (VBoolean: WordBool);
     varUnknown:  (VUnknown: Pointer);
     varByte:     (VByte: Byte);
     varString:   (VString: Pointer);
     varAny:      (VAny: Pointer);
     varArray:    (VArray: PVarArray);
     varByRef:    (VPointer: Pointer);
end;


Тут смотри какая бяка: при кастовании TGUID -> Variant путём простой перезапии Variant`а данными от TGUID`а в поле VType попадёт фигня полная, а не нормальный тип. В итоге первая же функция для работы с Variant`ами (тот же VarCopy) рухнет с ошибкой. То есть этот Variant даже присвоить другому нельзя.


Сергей М.   (2006-08-02 11:45:00) [6]


> Ты на каком Dlephi смотрел?


В 7-ке RawData предусмотрен.


> тут таких вещей нет


А неважно. Возможно, там аналогичный спецификатор как-то по-другому объявлен.

Если в 5-ке SizeOf(TVarData) = 16, этого вполне достаточно для решения задачи.

Приведи 5-шную декларацию структуры TVarData ..


Jeer   (2006-08-02 11:40:00) [7]

Ega23 ©   (02.08.06 11:27) [9]

Более того, использовать GUID в чистом виде в ключевых полях нерационально, т.к. приращение идет с конца, что плохо для индексации.
Для этого используют "перевернутый" GUID, для FB есть UDF.


Alkid   (2006-08-02 11:40:00) [8]

TVarData(v).RawData - undeclared identified 'Raw Data'.
Ты на каком Dlephi смотрел? У меня 5-ый, тут таких вещей нет.
Ладно, я смотрю извращаться придётся по-любому, а со строками это проще всего.


Jeer   (2006-08-02 11:37:00) [9]

Ega23 ©   (02.08.06 11:27) [9]

Для этого есть поле типа TGUID, но замечу, что в свойстве AsGUID используются неявно функции StringToGUID и GUIDToString


Сергей М.   (2006-08-02 11:31:00) [10]


> Alkid ©   (02.08.06 11:19) [6]


> в списке типов, поддерживаемых Variant`ом GUID не значится


Зато, заметь, SizeOf(TVarData) = SizeOf(TGUID).
Этого факта достаточно, чтобы в массиве TVarData(v).RawData хранить 16 байт, распределяемые под данные типа TGUID.


Ega23   (2006-08-02 11:27:00) [11]


> только объясни - зачем тебе Variant для GUID ?


Элементарно, Ватсон. Ключевое поле в БД, например.


Alkid   (2006-08-02 11:27:00) [12]

Да вот возникла производственная необходимость :)
Есть список пар <имя, значение>, ну и в нём потребовалось хранить значение типа GUID, а значения хранятся как Variant`ы. Вот такая пестня.
Короче не буду париться и запихну его как строку туда. Quick-and-Dirty.


Jeer   (2006-08-02 11:24:00) [13]


> Кроме того, замечу, что  в списке типов


Заметка была дана в [3].

Если охота "ломать башку" - TCustomVariantType и делай Custom Variant, только объясни - зачем тебе Variant для GUID ?


Alkid   (2006-08-02 11:19:00) [14]


var v : Variant;
   g : TGUID;
begin
 v := Variant(g);
end;

На присваивании исключение "Invalid variant conversion"
Оно и неудивительно, там (если в дизассемблер глянуть) идёт вызов VarCopy, куда передаётся GUID, трактуемый как Variant. А при такой трактовке получается инвалидный Variant. Кроме того, замечу, что  в списке типов, поддерживаемых Variant`ом GUID не значится. Так что вопрос остаётся, к ссожалению, открытым.


Сергей М.   (2006-08-02 11:11:00) [15]

v := variant(guid);
 guid := TGUID(v);


Alkid   (2006-08-02 11:08:00) [16]

Замечательно, но:

var v : Variant;
    g : TGUID;
begin
 v := g;
end;


При компиляции даёт ошибку:
[Error] Unit1.pas(30): Incompatible types: 'Variant' and 'TGUID'

Так что не всё так просто.


Jeer   (2006-08-02 10:59:00) [17]

F1 Variant types

By default, Variants can hold values of any type except records, sets, static arrays, files, classes, class references, and pointers. In other words, variants can hold anything but structured types and pointers.


Alkid   (2006-08-02 10:52:00) [18]

Проще говоря, как запихнуть его в Variant?


Jeer   (2006-08-02 10:47:00) [19]

А что значит "обращаться" ?
см TGUID тип


Наверх

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