Форум: "Основная";
Текущий архив: 2006.09.17;
Скачать: [xml.tar.bz2];
ВнизGUID + Variant = Love ? Найти похожие ветки
← →
Alkid © (2006-08-02 10:32) [0]Вопрос - как правильно обращаться с GUID`ами, когда их надо сохранять в Variant`e? Мне пока пришло в голову в строки их переводить, но это как-то некрасиво. Речиь идёт о Delphi 5.
← →
Jeer © (2006-08-02 10:47) [1]А что значит "обращаться" ?
см TGUID тип
← →
Alkid © (2006-08-02 10:52) [2]Проще говоря, как запихнуть его в Variant?
← →
Jeer © (2006-08-02 10:59) [3]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 11:08) [4]Замечательно, но:
var v : Variant;
g : TGUID;
begin
v := g;
end;
При компиляции даёт ошибку:
[Error] Unit1.pas(30): Incompatible types: "Variant" and "TGUID"
Так что не всё так просто.
← →
Сергей М. © (2006-08-02 11:11) [5]v := variant(guid);
guid := TGUID(v);
← →
Alkid © (2006-08-02 11:19) [6]
var v : Variant;
g : TGUID;
begin
v := Variant(g);
end;
На присваивании исключение "Invalid variant conversion"
Оно и неудивительно, там (если в дизассемблер глянуть) идёт вызов VarCopy, куда передаётся GUID, трактуемый как Variant. А при такой трактовке получается инвалидный Variant. Кроме того, замечу, что в списке типов, поддерживаемых Variant`ом GUID не значится. Так что вопрос остаётся, к ссожалению, открытым.
← →
Jeer © (2006-08-02 11:24) [7]
> Кроме того, замечу, что в списке типов
Заметка была дана в [3].
Если охота "ломать башку" - TCustomVariantType и делай Custom Variant, только объясни - зачем тебе Variant для GUID ?
← →
Alkid © (2006-08-02 11:27) [8]Да вот возникла производственная необходимость :)
Есть список пар <имя, значение>, ну и в нём потребовалось хранить значение типа GUID, а значения хранятся как Variant`ы. Вот такая пестня.
Короче не буду париться и запихну его как строку туда. Quick-and-Dirty.
← →
Ega23 © (2006-08-02 11:27) [9]
> только объясни - зачем тебе Variant для GUID ?
Элементарно, Ватсон. Ключевое поле в БД, например.
← →
Сергей М. © (2006-08-02 11:31) [10]
> Alkid © (02.08.06 11:19) [6]
> в списке типов, поддерживаемых Variant`ом GUID не значится
Зато, заметь, SizeOf(TVarData) = SizeOf(TGUID).
Этого факта достаточно, чтобы в массиве TVarData(v).RawData хранить 16 байт, распределяемые под данные типа TGUID.
← →
Jeer © (2006-08-02 11:37) [11]Ega23 © (02.08.06 11:27) [9]
Для этого есть поле типа TGUID, но замечу, что в свойстве AsGUID используются неявно функции StringToGUID и GUIDToString
← →
Alkid © (2006-08-02 11:40) [12]TVarData(v).RawData - undeclared identified "Raw Data".
Ты на каком Dlephi смотрел? У меня 5-ый, тут таких вещей нет.
Ладно, я смотрю извращаться придётся по-любому, а со строками это проще всего.
← →
Jeer © (2006-08-02 11:40) [13]Ega23 © (02.08.06 11:27) [9]
Более того, использовать GUID в чистом виде в ключевых полях нерационально, т.к. приращение идет с конца, что плохо для индексации.
Для этого используют "перевернутый" GUID, для FB есть UDF.
← →
Сергей М. © (2006-08-02 11:45) [14]
> Ты на каком Dlephi смотрел?
В 7-ке RawData предусмотрен.
> тут таких вещей нет
А неважно. Возможно, там аналогичный спецификатор как-то по-другому объявлен.
Если в 5-ке SizeOf(TVarData) = 16, этого вполне достаточно для решения задачи.
Приведи 5-шную декларацию структуры TVarData ..
← →
Alkid © (2006-08-02 12:00) [15]
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 даже присвоить другому нельзя.
← →
Lamer@fools.ua © (2006-08-02 12:04) [16]>>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
после окончания использования).
← →
Сергей М. © (2006-08-02 12:11) [17]
> Alkid © (02.08.06 12:00) [15]
Ну напиши свою функцию копирования .. Что , на VarCopy или прямом присваивании разве свет клином сошелся ?
На худой конец храни в варианте не сам GUID, а указатель на него .. Или храни как varArray ..
← →
Ega23 © (2006-08-02 12:21) [18]
> Более того, использовать GUID в чистом виде в ключевых полях
> нерационально, т.к. приращение идет с конца, что плохо для
> индексации.
> Для этого используют "перевернутый" GUID, для FB есть UDF.
>
Возможно. Но надо.
А какое-такое приращение?
← →
Jeer © (2006-08-02 12:30) [19]http://www.ibase.ru/devinfo/test2.htm
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2006.09.17;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.044 c