![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
ВDS 2006 тоже не поддерживает custom variant byRef
oxffff © (2006-09-14 23:21:00)Я уже писал о том, что 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-16 17:01:00) [1]ИМХО - это достаточная причина, чтобы вообще отказаться от использования вариантов.
Постойте. Постойте. Если использовать proxy, то никаких затруднений.
Пожалуйста подсоединяй DLL и используй. Нет необходимости получать адреса.
Proxy регистрится в EXE. и Использует DLL.
В чем причина то отказа.
jack128 (2006-09-16 16:36:00) [2]oxffff © (16.09.06 15:59) [39]
Ты еще не отказался от идеи реализовать на advanced record.
дык если нужно передовавать их между разными исполняемыми модулями - то это вообще невозможно. VTM то нету..
Не, естественно у классов (TCustomVarinatType) огромное приемущество над записями. Но и гемора настолько больше, что проще отказаться от их использования.
oxffff © (16.09.06 16:03) [40]
Таким образом, чтобы не усложнять себе жизнь нужно
использовать получение адреса.
Ну что поделаешь, если не позаботились об этом.
ИМХО - это достаточная причина, чтобы вообще отказаться от использования вариантов.
oxffff (2006-09-16 16:23:00) [3]Можно еще улучшить комбинацию и тогда вообще ничего подстраивать
TProxyCustomVarian.vartype = TExternalCustomVariant.vartype не нужно.
Твои соображения.
oxffff (2006-09-16 16:03:00) [4]Единственная проблема это осуществить, так чтобы
TProxyCustomVarian.vartype = TExternalCustomVariant.vartype.
Если будет одна DLL. То проблем не будет.
Если несколько, то придется подстраивать. Но можно.
Таким образом, чтобы не усложнять себе жизнь нужно
использовать получение адреса.
Ну что поделаешь, если не позаботились об этом.
oxffff (2006-09-16 15:59:00) [5]Ты еще не отказался от идеи реализовать на advanced record.
Есть же TCustomVariant.
oxffff (2006-09-16 15:54:00) [6]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:52:00) [7]>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;
jack128 (2006-09-16 15:48:00) [8]oxffff © (16.09.06 15:40) [34]
Получить адреса. При огромном желании можно.
Это не способ. За такие вещи - руки отрывать надо.
oxffff © (16.09.06 15:40) [34]
Второй способ использовать Proxy.
э-э-э.. Можно ссылку, что это такое?
oxffff (2006-09-16 15:44:00) [9]oxffff © (16.09.06 15:25) [30]
-нельзя перегрузить оператор = (его просто нет). Очистка не происходит
хм. Наверно имелось в виду := ? Опертор присваивания?
Да, Пардоню. именно :=
Для инстанцирования необязательно использовать виртульный конструктор.
VTB содержит верный instanceSize. а инициализация полей наследников не нужна (поскольку их нет). В обычном случае.
oxffff (2006-09-16 15:40:00) [10]Первый способ.
Получить адреса. При огромном желании можно.
Естественно не обычными средствами.
Второй способ использовать Proxy.
jack128 (2006-09-16 15:34:00) [11]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:30:00) [12]Один момент
jack128 (2006-09-16 15:26:00) [13]oxffff © (16.09.06 15:11) [28]
Естественно все организованы на использовании переменных модуля Variants
LVarTypeSync: RTLCriticalSection;LNextVarType:integer;LVarTypes:array of CustomVariantType
Они под implementation сидят. Как ты доступ к ним получишь??
oxffff (2006-09-16 15:25:00) [14]Таким образом в использовании инфраструктуры модуля variants есть необходимость.
проблемы универсально реализовать на advanced record.
-нельзя перегрузить оператор = (его просто нет). Очистка не происходит.
-добавление новых ?
Частные случаи на advanced record возможны.
oxffff (2006-09-16 15:17:00) [15]>Варианта собственно два: либо исходный код твоего custom variant'a >включен в EXE и тогда не важно где и как ты создал вариант - все >приведения будут работать, либо этого кода в EXE нету, и тогда в самом >EXE ты не сможешь использовать этот кастом вариант.
Смотри oxffff © (16.09.06 15:11) [28]
oxffff (2006-09-16 15:11:00) [16]первый способ
Передать
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 14:47:00) [17]Сейчас напишу.
jack128 (2006-09-16 14:41:00) [18]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:31:00) [19]Это сделать несложно в Dll реализуешь свои типы.
Далее подгружаешь DLL. И инстанцируешь неизвестные реализации custom variant естественно через метаклассы. Которые регистрируются в основном приложении. И теперь приложение знает о новых типах. Теперь приложение может копировать и приводить неизвествные типы допустим к string.
Безусловно не привести неизвестные к неизвестным.
Твое мнение.
oxffff (2006-09-16 14:25:00) [20]Не согласен.
Реализуешь потомка TCustomVariantType.
И далее методы Copy, Cast.
Я не говорю о приведении неизвестных типов к неизвестным.
Я говорю о приведении неизвестного к string
И о копировании неизвестного.