ООП SOM corba Delphi
Раздраконил свой генератор привязок до такого состояния, что уже заработала программа, использующая исключительно новые привязки.
Это пример для старых привязок, а
это — для новых. В старых привязках SOMObject — это указатель на запись, а все остальные классы — синонимы SOMObject, то есть, контроля типов нет. В старых привязках, чтобы узнать тип аргумента, нужно было в процедурном стиле написать ParameterDef__get_type, а вот имя аргумента объявлялось в Contained, поэтому Contained__get_name, а так как вручную мне лень синонимы везде прописывать, то только по таким именам работало. В новых привязках генератор собирает все методы класса в одну общую кучу, и всё работает достаточно очевидным образом с вызовом методов через точку. И даже атрибуты CORBA спроецировались на свойства Delphi. Поскольку в Delphi жалкое одиночное наследование, генерить список методов требуется каждый раз сначала, и именно это и делается, зато потом удобно.
Работает это посредством того хака, что создаются объекты SOM, а Delphi думает, что это объекты Delphi. Так как с точки зрения Delphi методы статические, Delphi не лезет в VMT, делает статический вызов, в нём написан код, который направит вызов в SOM, и оно там пойдёт куда надо. Ещё немного пошаманил, чтобы волшебным образом работали классовые функции. Классовые функции могут вызываться как у объектов, и тогда Delphi пытается взять из объекта VMT по нулевому смещению, а может — непосредственно у класса, и тогда берётся статический адрес VMT. Учитывая, что с точки зрения Delphi классы друг от друга не наследуются, отличить эти случаи не сложно. Нужно просто сравнить Self со своим именем, и если да, то нас вызвали через имя класса, и класс-объект нужно искать одним способом, а если нет, то нас вызвали как метод объекта, и надо ещё раз разъименовать Self, и там будет лежать указатель на класс-объект.
Немного подкрутил, чтобы в результате метода SOMObject.somGetClass учитывался метакласс. Была мысль вообще все методы метакласса спроецировать на классовые функции и процедуры, но потом посмотрел, сколько там всего в SOMClass, и решил, что не надо. Тем более, что в SOM.IR публично показан только один метакласс, SOMMSingleInstance. Но даже ради него подкрутил, чтобы у метода SOMObject.somGetClass возвращался именно указанный метакласс, а не просто SOMClass. Кстати, так получается, что с точки зрения языковой проекции метаклассы не могут так просто наследоваться. То есть, умом-то мы понимаем, что компилятор SOM гарантирует совместимость метаклассов, но вот во что это спроецировать, открытый вопрос. Если мы наследуемся от двух классов с разными метаклассами, то метакласс потомка будет заведомо принадлежать пересечению множеств потомков каждого метакласса, и что, для этого динамически создаваемого метакласса тоже создавать привязки? А там по цепочке ещё для метаклассов более высокого порядка может потребоваться автоматическое создание. Одно дело — когда движок SOM это создаёт, и другое дело — когда генерится текст. Я решил, что этого делать не нужно, а раз так, то даже, если был класс A с указанием метакласса M_A, и от него наследуется класс B, то, если B не укажет явно тот же метакласс, что и A, в его привязках будет опять обычный SOMClass.
Естественно, все методы обычного TObject не будут работать. Я эту проблему пытаюсь решить, скрывая их при помощи reintroduce в private. Только операция as портит картину. Её не спрячешь, но хотя бы заменил методами, приводящими тип вверх и вниз. Вот так, с небольшой порцией магии создаётся впечатление, что SOM в Delphi как родная. Классы, методы, свойства.