Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.10.29;
Скачать: [xml.tar.bz2];

Вниз

ВDS 2006 тоже не поддерживает custom variant byRef   Найти похожие ветки 

 
oxffff ©   (2006-09-14 23:21) [0]

Я уже писал о том, что Delphi 7 не поддерживает custom variant by ref. Дисскуссия шла где в июне-июля. Уже в архивах.
Сейчас установил BDS 2006. Решил проверь, а как же там дела с этим. К сожалению все также.

Ну во первых естественно в вызове VarCopy->VarCopyDeep

И далее строчки
 // otherwise try for custom
 else if FindCustomVariantType(Source.VType, LSourceHandler) then
   LSourceHandler.Copy(Dest, Source, False)

Во первых FindCustomVariantType не найдет custom variant.
И во вторых вызывается direct copy

Если вызвать VarCopyNoInd(a,b).

То все равно будет ошибка поскольку FindCustomVariantType не найдет helper класс .

Кто хочет убедиться пожалуйста код

var a,b:variant;
begin
//here some custom variant by ref
tvardata(a).VType:=273 or varByRef;
a:=b; exception is generated
VarCopyNoInd(a,b); exception is generated

QC молчит.


 
oxffff ©   (2006-09-14 23:25) [1]

Естественно приведенный код не требует helper класса. Поскольку до него дело не дойдет по причине  FindCustomVariantType не работает с By ref.
Естественно поправить ее очень легко. Я уже писал об этом летом.


 
jack128 ©   (2006-09-15 02:07) [2]

проще написать свой record, перегрузив нужные операторы, чем с этими вариантами парится.


 
oxffff ©   (2006-09-15 10:12) [3]

Собственно сабж посвещен тому, чтобы указать,
что custom variant byRef не поддерживается нормальными средствами.


 
oxffff ©   (2006-09-15 10:20) [4]

to jack128.
Это совсем не проще поскольку придется городить аналогичную инфраструктуру.


 
jack128 ©   (2006-09-15 12:51) [5]

oxffff ©   (15.09.06 10:20) [4]
Это совсем не проще поскольку придется городить аналогичную инфраструктуру.


какую такую инфроструктуру??  
Единственный недостаток(правда очень существенный) - отсутствие у записей деструкторов и не возможность переопределить конструктор по умолчанию..


 
jack128 ©   (2006-09-15 12:52) [6]

jack128 ©   (15.09.06 12:51) [5]
не возможность переопределить конструктор по умолчанию..

в смысле - это не недостаток. Это так.. Хотелка..


 
Джо ©   (2006-09-15 13:48) [7]

> [6] jack128 ©   (15.09.06 12:52)
> jack128 ©   (15.09.06 12:51) [5]
> не возможность переопределить конструктор по умолчанию..
> в смысле - это не недостаток. Это так.. Хотелка..

Если записям все это добавить, плюс еще чего нафантазировать, то это уже будут не записи, а, практически, классы. Главное — вовремя остановиться! :)


 
oxffff ©   (2006-09-15 14:12) [8]

to jack128
Причем чем здесь вообще конструктор. Вам внимательнее надо читать сабж.
Нужно определить свой custom variant. И передать его как by ref.
varCopy не делает этого, и даже пытается сделать это некорректно. Поскольку не расчитана вообще на custom byref

Вы написали что можно выкрутиться с помощью anvanced record в BDS 2006.

то есть вы предлагаете сделать аналог модуля variants, а именно сделать
аналогично varCopy, varCopyNoInd, TCustomVariantType, TInvokeableVariantType и т.д. Если вы это сделаете, то я вам буду благодарен. Но стоит ли оно того.


 
oxffff ©   (2006-09-15 14:16) [9]

> jack128
> какую такую инфроструктуру??  
> Единственный недостаток(правда очень существенный) - отсутствие у
> записей деструкторов и не возможность переопределить конструктор по >умолчанию..

Ага добавить туда еще VMT И DMT и вообще тогда будет advanced object.


 
jack128 ©   (2006-09-16 03:42) [10]

Джо ©   (15.09.06 13:48) [7]
то это уже будут не записи, а, практически, классы.

вобщем то это и нужно.  Классы, автоматом уничтожаемые при выходе за область видимости.  Как в С++.

oxffff ©   (15.09.06 14:12) [8]
а именно сделать
аналогично varCopy, varCopyNoInd, TCustomVariantType, TInvokeableVariantType и т.

зачем varCopy , записи и так нормально копируются оператором присваивания. TCustomVariantType - это как раз и есть  запись. От тя треба только переопределить нужные те операторы и привидения к нужным типам.


 
oxffff ©   (2006-09-16 04:24) [11]

to jack128
> TCustomVariantType - это как раз и есть  запись.

О как. Это не запись.


 
jack128 ©   (2006-09-16 04:27) [12]

oxffff ©   (16.09.06 4:24) [11]
О как. Это не запись.

Ты не понял.  Я имею в виду, что аналогом TCustomVariantType в предложенной мною схеме является запись.


 
oxffff ©   (2006-09-16 04:29) [13]

to jack128
Уважаемый на этом вы далеко не уедите.
О как насчет того, что есть custom variant произвольный (неизвестный).
И перегрузить операторы не удастся.
Тогда вам придется городить аналогию с  TCustomVariantType, TInvokeableVariantType.


 
oxffff ©   (2006-09-16 04:30) [14]

> Я имею в виду, что аналогом TCustomVariantType в предложенной мною >
>схеме является запись.

Подробнее.


 
oxffff ©   (2006-09-16 04:32) [15]

TCustomVariantType is the base class for Delphi custom variant types.
TCustomVariantType descendants do not represent the Variants themselves. Rather, they act as utility classes that the custom Variants call on to perform their operations.


 
oxffff ©   (2006-09-16 04:34) [16]

Вообщем то сабж посвещен тому, что у меня нет проблемы с реализацией.
Сабж посвещен тому что указать, что был недостаток. И также и остался.

Но мне интересно, что ты хочешь предложить.


 
oxffff ©   (2006-09-16 05:07) [17]

to jack128
Ваш способ не подойдет.
Допустим мы знаем все custom variant. Все операторы перегружены.
Но в  предложенном тобой способе есть проблема.

При перегрузки присваивания Приемник просто перетирается.
Нет способа вызвать varclear.


 
jack128 ©   (2006-09-16 05:26) [18]

oxffff ©   (16.09.06 4:34) [16]
Но мне интересно, что ты хочешь предложить.


type
 TComplex = record
 public
   Re: Double;
   Im: Double;
   constructor Create(_Re, _Im: Double);    
   class operator Add(const A, B: TComplex): TComplex; // сложение
   class operator Implicit(A : TComplex) : string; // неявное приведение к строке
 end;

var
 A, B, C: TComplex;
begin
 A := TComplex.Create(10, 20);
 B := TComplex.Create(20, 10);
 C := A + B;
 Edit1.Text := C;
end;

 
oxffff ©   (16.09.06 5:07) [17]
При перегрузки присваивания Приемник просто перетирается.
Нет способа вызвать varclear.

Я заметил:
jack128 ©   (15.09.06 12:51) [5]
Единственный недостаток(правда очень существенный) - отсутствие у записей деструкторов

varclear - это и есть деструктор.


 
oxffff ©   (2006-09-16 06:03) [19]

А если учесть, что на этапе компиляции мы не можем опеределить все типы.
То есть не перегрузим все операторы.
Тогда как ты бы выкрутился?


 
jack128 ©   (2006-09-16 06:21) [20]

oxffff ©   (16.09.06 6:03) [19]
Э-э-э. Я не понял вопроса.
Ты _всегда_ знаешь к каким типам можно привести тип TComplex и какие типы можно привести к типу TComplex. Соответствующие опреторы привидения и перегуружаешь.  В чем проблема то??


 
oxffff ©   (2006-09-16 13:00) [21]

А если я определю тип, который неизвестен на этапе компиляции.


 
oxffff ©   (2006-09-16 13:05) [22]

Ну допустим использую сторонний DLL, в котором есть новый произвольный тип. Основное приложение понятия не имеет как с ним работать. Но должно допустим копировать его, или приводить допустим к типу string;


 
jack128 ©   (2006-09-16 14:18) [23]

oxffff ©   (16.09.06 13:05) [22]
Ну допустим использую сторонний DLL, в котором есть новый произвольный тип. Основное приложение понятия не имеет как с ним работать. Но должно допустим копировать его, или приводить допустим к типу string;


так как и с вариантами - естественно ничего не заработает.


 
oxffff ©   (2006-09-16 14:25) [24]

Не согласен.
Реализуешь потомка TCustomVariantType.
И далее методы Copy, Cast.

Я не говорю о приведении неизвестных типов к неизвестным.
Я говорю о приведении неизвестного к string
И о копировании неизвестного.


 
oxffff ©   (2006-09-16 14:31) [25]

Это сделать несложно в Dll реализуешь свои типы.
Далее подгружаешь DLL. И инстанцируешь неизвестные реализации custom variant естественно через метаклассы. Которые регистрируются в основном приложении. И теперь приложение знает о новых типах. Теперь приложение может копировать и приводить неизвествные типы допустим к string.
Безусловно не привести неизвестные к неизвестным.

Твое мнение.


 
jack128 ©   (2006-09-16 14:41) [26]

oxffff ©   (16.09.06 14:31) [25]
И инстанцируешь неизвестные реализации custom variant естественно через метаклассы. Которые регистрируются в основном приложении.

я универов не кончал, можно без страшных слов, как нить попроще, с примером желательно.

Варианта собственно два: либо исходный код твоего custom variant"a включен в EXE и тогда не важно где и как ты создал вариант - все приведения будут работать, либо этого кода в EXE нету, и тогда в самом EXE ты не сможешь использовать этот кастом вариант.
Пример:
DLL:
uses
 SysUtils,
 Classes,
 VarCmplx;

{$R *.res}

function GetFirst: Variant;
begin
 Result := VarComplexCreate(10, 20);
end;

function GetSecond: Variant;
begin
 Result := VarComplexCreate(20, 10);
end;

exports
 GetFirst, GetSecond;


EXE:


uses VarCmplx; //если строка закоментирована, то получим Invalid variant operation.

function GetFirst: Variant; external "Vars.dll" name "GetFirst";
function GetSecond: Variant; external "Vars.dll" name "GetSecond";

procedure TForm8.FormCreate(Sender: TObject);
begin
 Caption := GetFirst + GetSecond;
end;


 
oxffff ©   (2006-09-16 14:47) [27]

Сейчас напишу.


 
oxffff ©   (2006-09-16 15:11) [28]

первый способ
Передать
LVarTypeSync: RTLCriticalSection;LNextVarType:integer;LVarTypes:array of CustomVariantType

EXE

function RegisterExternal(const LVarTypeSync: RTLCriticalSection;var LNextVarType:integer;var LVarTypes:array of CustomVariantType); external "Other.dll" name RegisterExternal";

Второй способ

Получить из DLL пары значений TVarType, инстанс CustomVariantType.
И зарегистрировать в EXE.

Третий способ

TExternalCustomVariant=class
constructor create(Const LVarTypeSync: RTLCriticalSection;var LNextVarType:integer;var LVarTypes:array of CustomVariantType);
end;

TExternalCustomVariantClass=class of TExternalCustomVariant;

EXE

Получить из DLL все TExternalCustomVariantClass. И инстанцировать.

Естественно все организованы на использовании переменных модуля Variants

LVarTypeSync: RTLCriticalSection;LNextVarType:integer;LVarTypes:array of CustomVariantType


 
oxffff ©   (2006-09-16 15:17) [29]

>Варианта собственно два: либо исходный код твоего custom variant"a >включен в EXE и тогда не важно где и как ты создал вариант - все >приведения будут работать, либо этого кода в EXE нету, и тогда в самом >EXE ты не сможешь использовать этот кастом вариант.

Смотри oxffff ©   (16.09.06 15:11) [28]


 
oxffff ©   (2006-09-16 15:25) [30]

Таким образом в использовании инфраструктуры модуля variants есть необходимость.

проблемы универсально реализовать на advanced record.  
-нельзя перегрузить оператор = (его просто нет). Очистка не происходит.
-добавление новых ?

Частные случаи на advanced record возможны.


 
jack128 ©   (2006-09-16 15:26) [31]

oxffff ©   (16.09.06 15:11) [28]
Естественно все организованы на использовании переменных модуля Variants

LVarTypeSync: RTLCriticalSection;LNextVarType:integer;LVarTypes:array of CustomVariantType


Они под implementation сидят. Как ты доступ к ним получишь??


 
oxffff ©   (2006-09-16 15:30) [32]

Один момент


 
jack128 ©   (2006-09-16 15:34) [33]

oxffff ©   (16.09.06 15:25) [30]
-нельзя перегрузить оператор = (его просто нет). Очистка не происходит

хм.  Наверно имелось в виду := ? Опертор присваивания?

oxffff ©   (16.09.06 15:25) [30]
-добавление новых ?

Я пока не вижу как новые варианты добавить ;-)
Прямой доступ к LVarTypes невозможен, и создание TCustomVariantType по классовой ссылке, переданной из DLL тоже не возможно, так как у TCustomVariantType конструктор не виртуальный. Разве что сделать наследника от него с виртуальным конструктором и завязаться именно на этого наследника. Ну и плюс - проблемы с передачей классов из dll в exe. Нужно шерстить код Variants.pas на наличие операторов is/as и тому подобных..


 
oxffff ©   (2006-09-16 15:40) [34]

Первый способ.
Получить адреса. При огромном желании можно.
Естественно не обычными средствами.

Второй способ использовать Proxy.


 
oxffff ©   (2006-09-16 15:44) [35]

oxffff ©   (16.09.06 15:25) [30]
-нельзя перегрузить оператор = (его просто нет). Очистка не происходит
хм.  Наверно имелось в виду := ? Опертор присваивания?

Да, Пардоню. именно :=

Для инстанцирования необязательно использовать виртульный конструктор.
VTB содержит верный instanceSize. а инициализация полей наследников не нужна (поскольку их нет). В обычном случае.


 
jack128 ©   (2006-09-16 15:48) [36]

oxffff ©   (16.09.06 15:40) [34]
Получить адреса. При огромном желании можно.

Это не способ.  За такие вещи - руки отрывать надо.

oxffff ©   (16.09.06 15:40) [34]
Второй способ использовать Proxy.

э-э-э..  Можно ссылку, что это такое?


 
oxffff ©   (2006-09-16 15:52) [37]

>oxffff ©   (16.09.06 15:40) [34]
>Получить адреса. При огромном желании можно.
>Это не способ.  За такие вещи - руки отрывать надо

????? А что если очень нужно.

oxffff ©   (16.09.06 15:40) [34]
Второй способ использовать Proxy.
э-э-э..  Можно ссылку, что это такое?

TProxyCustomVariant.

DLL TCustomvariant<>  EXE TProxyCustomVariant <> клиент

TProxyCustomVariant=class(TCustomvariant)
public
contructor create(ExternalCustom:TProxyCustomVariant)
end;


 
oxffff ©   (2006-09-16 15:54) [38]

TProxyCustomVariant=class(TCustomvariant)
public
contructor create(ExternalCustom:TProxyCustomVariant)
end;

procedure TProxyCustomVariant.Clear(var V: TVarData);
begin
ExternalCustom.clear(V);
end;


 
oxffff ©   (2006-09-16 15:59) [39]

Ты еще не отказался от идеи реализовать на advanced record.

Есть же TCustomVariant.


 
oxffff ©   (2006-09-16 16:03) [40]

Единственная проблема это осуществить, так чтобы
TProxyCustomVarian.vartype = TExternalCustomVariant.vartype.

Если будет одна DLL. То проблем не будет.
Если несколько, то придется подстраивать. Но можно.

Таким образом, чтобы не усложнять себе жизнь нужно
использовать получение адреса.
Ну что поделаешь, если не позаботились об этом.



Страницы: 1 2 вся ветка

Форум: "Основная";
Текущий архив: 2006.10.29;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.56 MB
Время: 0.04 c
2-1161066498
Bless
2006-10-17 10:28
2006.10.29
Два класса, ссылающиеся друг на друга, в разных модулях. Можно?


2-1160465616
B0Bka
2006-10-10 11:33
2006.10.29
МП3 таг


15-1160057772
ArtemESC
2006-10-05 18:16
2006.10.29
Работа...


11-1124596891
L505
2005-08-21 08:01
2006.10.29
How to help KOL development?


15-1159915299
Multy
2006-10-04 02:41
2006.10.29
Ну и что это за уродство?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский