AN> вроде этот вопрос уже поднимался, но я не могу найти: можно ли при передаче
AN> в процедуру ANY-параметра определить в процедуре его тип, т.е. чё было было
AN> передано STRING, LONG али ещё чего:AN> Пример:
AN> SomeProc PROCEDURE(? Param)
AN> code
AN> !вот здесь хочется узнать тип переданного Param и в зависимости от этого
AN> учинить определённые действия
Легально можно узнать только, что переменная, скрытая под ANY, является строкой или нет. Для получения более детальной информации необходимо уже работать непосредственно с самим UFO-обьектом, который скрыт под ANY-оберткой. Проще всего воспользоваться INTERFACE-механизмом и с его помощью использовать методы UFO-обьекта. Уже на протяжении трех версий C50/C55/C60 структура VMT для UFO-обьекта остается неизменной, что позволяет использовать единый INTERFACE для этих версий. Измениться-ли он в будущих версиях — х/з, но хочется надеятся, что нет.
Итак:
TUFO_CallInterface INTERFACE,TYPE
Dummy1 PROCEDURE
Dummy2 PROCEDURE
Dummy3 PROCEDURE
Dummy4 PROCEDURE
Dummy5 PROCEDURE
_Type PROCEDURE(LONG _UFOaddr),LONG
Dummy6 PROCEDURE
Dummy7 PROCEDURE
Dummy8 PROCEDURE
Dummy9 PROCEDURE
Dummy10 PROCEDURE
Dummy11 PROCEDURE
Dummy12 PROCEDURE
Dummy13 PROCEDURE
Dummy14 PROCEDURE
Dummy15 PROCEDURE
Dummy16 PROCEDURE
_Address PROCEDURE(LONG _UFOaddr),LONG
Dummy17 PROCEDURE
Dummy18 PROCEDURE
Dummy19 PROCEDURE
Dummy20 PROCEDURE
_Max PROCEDURE(LONG _UFOaddr),LONG
_Size PROCEDURE(LONG _UFOaddr),LONG
END
Набор методов немного неполный.
Как легко заметить из описания, вызов методов несколько необычен. Т.е. реально вызов метода, например _Type, выглядит как _Type(LONG _UFOaddr,LONG _UFOaddr).
Причем предполагается, что оба параметра одинаковы. Зачем так сделано? Это связано с несколько нестандартным вариантом вызова методов UFO-обькта. О чем, кстати, я уже как-то писал в данной рассылке. В этих методах предполагается, что адрес самого обьекта передается не в EAX, а в EBX! А в EAX, кстати, некоторые методы предполагают получать один их параметров вызова! Именно поэтому остальные методы в данном описании не используются, т.к. через INTERFACE-механизм невозможно использовать EAX иначе чем для передачи адреса обьекта. Такой-же нестандартный вариант вызовов используется в Кларионе еще в нескольких обьектах. Но, как я уже писал, опять-же, в данной рассылке, в C60 работа с новыми обьектами построена уже по стандартному варианту. И с ними уже проще работать. Очевидно разработчики SV понемногу «разворачиваются» к обычным
программистам и дают возможность нам «забраться» в RTL.
Что не может не радовать!
Однако, что-то я отвлекся!
_Type - возвращает тип переменной, скрытой под ANY-оберткой.
Расшифровку типов можно посмотреть в LIBSRCEQUATES.CLW
_Address - возвращает адрес переменной, на которую ссылается
данный UFO-обьект.
_Max - возвращает кол-во элементов в текущей размерности массива.
Для обычных переменных возвращает 0.
_Size - возвращает размер переменной, на которую ссылается
данный UFO-обьект.
Для массивов возвращает ПОЛНЫЙ размер массива.
Как с этим работать?
MAP
MyProc(*? _Var)
END
UFO &TUFO_CallInterface
Var DECIMAL(11,2)
Any ANY
...
Any &= Var
UfoAddr# = Address(Any)
OMIT('***',_C55_)
Peek(UfoAddr#,UfoAddr#) ! Только для C50
***
UFO &= (UfoAddr#)
Type# = UFO._Type(UfoAddr#)
Dim# = UFO._Max(UfoAddr#) ! Массив?
if Dim#
Message('Массив из '& Dim# &' элементов типа '& Type#)
else
Message('Переменная типа '& Type#)
.
MyProc(Var)
...
MyProc Procedure(*? _Var)
Code
UfoAddr# = Address(_Var)
OMIT('***',_C55_)
Peek(UfoAddr#,UfoAddr#) ! Только для C50
***
UFO &= (UfoAddr#)
Type# = UFO._Type(UfoAddr#)
Dim# = UFO._Max(UfoAddr#) ! Массив?
if Dim#
Message('Массив из '& Dim# &' элементов типа '& Type#)
else
Message('Переменная типа '& Type#)
.
Return
Я показал два примера использования UFO-обьекта.
Прямо в коде программы и в процедуре.
Все абсолютно работоспособно в C50/C55/C60.
