Re[6]: Reflection for C++
От: yxiie Украина www.enkord.com
Дата: 07.03.05 17:37
Оценка:
Здравствуйте, hth, Вы писали:

hth>Just FYI http://agenda.cern.ch/fullAgenda.php?ida=a051238

hth>см. "Fermilab trip report — C++, Reflex and the Standards Committee"
hth>В двух словах — поступило предложение добавить reflection в стандарт языка.
hth>будем внимательно следить за событиями

пока они внесут в стандарт, а потом пока производители компиляторов реализуют...
чувствую придется и дальше велосипед свой дописывать...
... << RSDN@Home 1.1.3 stable >>
Re[5]: Reflection for C++
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 07.03.05 18:43
Оценка:
Здравствуйте, yxiie, Вы писали:

Y>Здравствуйте, eao197, Вы писали:


Y>>>да, знаем, есть такое, но не хватало мне ограничить себя GCC, это вообще пипец.

Y>>>либа нужна чисто на C++ без всяких хитрых хаков, парсеров, DDL, выдирания информации из Debug и.т.д.

E>>Боюсь, что если без парсеров и DDL, то объем ручного программирования в конце-концов приведет к невозможности использования такого решения.


Y>ну можно на макросах...


Вообще-то я имел в виду нечто другое. Конечно, описывать сериализуемые атрибуты, явно назначая им строковые имена, плохо. Лучше, если строковые имена будут назначаться автоматически из C++ имени атрибута (через макрос, парсер или DDL). Более важный вопрос -- это вызов метода объекта через reflection. Вот как это предлагал Batiskaf:

typedef    TYPELIST_4(    const std_string&, 
                        unsigned char, 
                        const std_string&,
                        unsigned int )                ConstructorParamList;
typedef    Loki::Functor<    TheObject*, 
                        ConstructorParamList >            Constructor;

//В случае отстутствия конструктора с таким прототипом будет выброшено исключение 
//подобная стратегия применяется для всех запросов к метаклассу
Constructor    ctor = 
                        pClass->GetConstructor<    ConstructorParamList>();

//Создание экземпляра обьекта с вызовом полученного конструктора
TheObject* pObj = ctor("Vasya", 27, "London", 12 );


Вот эти вот описания ConstructorParamList и Constructor:
— во-первых, напрочь лишают нас преимуществ статической типизации. На момент компиляции этой инструкции компилятор не в состоянии проверить, есть ли у класса конструктор с таким набором параметров;
— во-вторых, изменение прототипа конструктора приведет к необходимости правки кода, вызывающего этот конструктор через reflection. Если таких фрагментов много, то очень высока вероятность того, что где-то мы забудем сделать исправления и получим run-time ошибку в самый неподходящий момент.

Для преодоления второй проблемы описания ConstructorParamList и Constructor можно сделать в каком-то заголовочном файле, в одном месте на весь проект. Но, эти объявления все равно окажутся оторванными от реального конструктора и компилятор не сможет проводить статическую проверку типов. Тогда возникает вопрос: а почему бы не сделать следующий логический шаг и не определить интерфейс фабрики:

class    MyClassNameIface
    {
    public :
        MyClassName *
        construct(
            const std::string &,
            unsigned char,
            const std::string &,
            unsigned int );
        ...
    };


И через reflection получать указатель на экземпляр, реализующий этот интерфейс?
Тогда мы получаем нормальную статическую типизации.

Такого же мнения я придерживаюсь и по поводу вызовов методов объектов через reflection вообще. В принципе, в большинстве случаев, нет смысла вызывать неизвестно какой метод неизвестно у какого объекта. Обычно мы имеем дело со строго определенными интерфейсами. И наличие таких интерфейсов в виде нормальных C++ классов позволяет повысить безопасность программ за счет статической типизации. И для вызовов методов reflection, по сути, должен превратится в способ получение указателей на объекты, которые реализуют нужные нам интерфейсы, фактически в некоторую умную фабрику.

С доступом к атрибутам объектов ситуация не такая однозначная, как с методами. Хотя, изменять значение атрибута через reflection -- это нарушение принципов полиморфизма: может быть setter для этого атрибута выполняет хитрые преобразования или проверки, а мы их таким суровым образом обходим. Другое дело сериализация/десериализация. Ведь тогда мы, по сути, выполняем просто сохранение снимка объекта и восстановление объекта по снимку. Но и в этом случае reflection вырождается в сериализацию, для которой уже масса решений существует.

E>>Ведь сам оцени, во что выльется сопровождение кода в варианте Batiskaf-а, если потребуется изменить формат метода, который вызывается через reflection?


Y>все равно придется как-то описвать структуру, так пусть лучше это будет несколько макросов на месте, чем еще какие-то левые файлы или тулзы, которые нужно вызывать перед компиляцией.


Я бы не был столь категоричен:
1. Написание макросов или какого-то кода вручную черевато ошибками. И требует больших трудозатрат.
2. Запуск каких-либо дополнительных инструментов для генерации вспомогательного C++ кода -- это обычная практика. Так поступают и при работе с lex/flex/yacc/bison, и при работе с ANTLR, и при работе с Qt. При наличии нормального инструмента по управлению компиляцией это вообще не проблема (tmake для Qt скрывает от программиста детали преобразования ui-файлов в cpp, а cpp-файлов в moc).
3. С помощью внешних описаний схемы данных можно достигать таких возможностей, которые на уровне макросов в крайне сложно, если вообще возможно, реализовать. Например, поддержку необязательных атрибутов при сериализации. Т.е., если атрибут содержит значение по-умолчанию, то атрибут можно не сериализовать, что экономит и время и место.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[6]: Reflection for C++
От: yxiie Украина www.enkord.com
Дата: 07.03.05 19:12
Оценка:
Здравствуйте, eao197, Вы писали:

E>Такого же мнения я придерживаюсь и по поводу вызовов методов объектов через reflection вообще. В принципе, в большинстве случаев, нет смысла вызывать неизвестно какой метод неизвестно у какого объекта.


есть. рефлексия мне нужна как я уже говорил в первую очередь для простого и гибкого скрипт-языка типа JavaScript на котором будет производится манипуляция объектами приложения, и там мы имеем просто:

var myObject;

E>Обычно мы имеем дело со строго определенными интерфейсами. И наличие таких интерфейсов в виде нормальных C++ классов позволяет повысить безопасность программ за счет статической типизации. И для вызовов методов reflection, по сути, должен превратится в способ получение указателей на объекты, которые реализуют нужные нам интерфейсы, фактически в некоторую умную фабрику.


speak for yourself. в том то и дело, что мне рефлексия не для сериализации нужна, а в первую очередь для удобного script-binding.

E>С доступом к атрибутам объектов ситуация не такая однозначная, как с методами.


да хрен с ними, с атрибутами. если сильно нужно, я бы мог и без них обойтись.

E>Хотя, изменять значение атрибута через reflection -- это нарушение принципов полиморфизма: может быть setter для этого атрибута выполняет хитрые преобразования или проверки, а мы их таким суровым образом обходим. Другое дело сериализация/десериализация. Ведь тогда мы, по сути, выполняем просто сохранение снимка объекта и восстановление объекта по снимку.


эх не знаю, это наверное только в сказке так — сделал снимок, и восстановил по нем

E>Но и в этом случае reflection вырождается в сериализацию, для которой уже масса решений существует.


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

E>>>Ведь сам оцени, во что выльется сопровождение кода в варианте Batiskaf-а, если потребуется изменить формат метода, который вызывается через reflection?


Y>>все равно придется как-то описвать структуру, так пусть лучше это будет несколько макросов на месте, чем еще какие-то левые файлы или тулзы, которые нужно вызывать перед компиляцией.


E>Я бы не был столь категоричен:

E>1. Написание макросов или какого-то кода вручную черевато ошибками. И требует больших трудозатрат.
E>2. Запуск каких-либо дополнительных инструментов для генерации вспомогательного C++ кода -- это обычная практика. Так поступают и при работе с lex/flex/yacc/bison, и при работе с ANTLR, и при работе с Qt. При наличии нормального инструмента по управлению компиляцией это вообще не проблема (tmake для Qt скрывает от программиста детали преобразования ui-файлов в cpp, а cpp-файлов в moc).
E>3. С помощью внешних описаний схемы данных можно достигать таких возможностей, которые на уровне макросов в крайне сложно, если вообще возможно, реализовать. Например, поддержку необязательных атрибутов при сериализации. Т.е., если атрибут содержит значение по-умолчанию, то атрибут можно не сериализовать, что экономит и время и место.

мне не нужно таких масштабов. мне нужно просто сделать отображение иерархии.
у меня сейчас приложение — это динамическая отображенная именованая иерархия, части которой постоянно меняются. что-то загружается из xml, что-то генерируется в ран-тайм, где по имени можно оперировать любым объектом. вот такое мне и нужно, только уже готовое и отлаженое, и не надо меня переубеждать
... << RSDN@Home 1.1.3 stable >>
Re[7]: Reflection for C++
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 07.03.05 21:15
Оценка:
Здравствуйте, yxiie, Вы писали:

<...>

Y>мне не нужно таких масштабов. мне нужно просто сделать отображение иерархии.

Y>у меня сейчас приложение — это динамическая отображенная именованая иерархия, части которой постоянно меняются. что-то загружается из xml, что-то генерируется в ран-тайм, где по имени можно оперировать любым объектом. вот такое мне и нужно, только уже готовое и отлаженое, и не надо меня переубеждать

Ok. Просто стало понятно, что тебе необходимо.

Но я думаю, что тебе не reflection нужен, а интеграция скриптового языка и C++ кода. Может посмотреть, как это сделано в таких языках, как Python, Ruby (там, имхо, попроще, чем в Python), Lua?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[8]: Reflection for C++
От: yxiie Украина www.enkord.com
Дата: 07.03.05 21:35
Оценка:
Здравствуйте, eao197, Вы писали:

E>Ok. Просто стало понятно, что тебе необходимо.


E>Но я думаю, что тебе не reflection нужен, а интеграция скриптового языка и C++ кода. Может посмотреть, как это сделано в таких языках, как Python, Ruby (там, имхо, попроще, чем в Python), Lua?


не совсем. мне не нужно ничего интегрировать, т.к. скрипт-язык сам будет частью системы, в этом то и прикол. если бы мне нужно было просто прикрутить скрипт-язык я бы просто взял boost.python или luabind и не парился. Тут нужно иметь общую иерархию, с которой можно было сравнительно одинаково удобно работать как на С++ (там где нужна скорость) так и на скрипт-языке (там где скорость не критична). плюс всякие бонусы типа сериализации приветствуются.
... << RSDN@Home 1.1.3 stable >>
Re[9]: Reflection for C++
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 08.03.05 04:59
Оценка:
Здравствуйте, yxiie, Вы писали:

Y>Здравствуйте, eao197, Вы писали:


E>>Ok. Просто стало понятно, что тебе необходимо.


E>>Но я думаю, что тебе не reflection нужен, а интеграция скриптового языка и C++ кода. Может посмотреть, как это сделано в таких языках, как Python, Ruby (там, имхо, попроще, чем в Python), Lua?


Y>не совсем. мне не нужно ничего интегрировать, т.к. скрипт-язык сам будет частью системы, в этом то и прикол. если бы мне нужно было просто прикрутить скрипт-язык я бы просто взял boost.python или luabind и не парился. Тут нужно иметь общую иерархию, с которой можно было сравнительно одинаково удобно работать как на С++ (там где нужна скорость) так и на скрипт-языке (там где скорость не критична). плюс всякие бонусы типа сериализации приветствуются.


А ты можешь, если это не секрет, поделится своими идеями на этот счет? А то я, например, не очень понимаю такую вещь. Вот, допустим, в твоем скрипте есть строки:

MyObject my;
my.sayThis( "Hello, world!", Color::red );


Я не помнимаю, как для такого кода, с помощью решения Batiskaf-а ты сделаешь вызов метода C++ объекта. Ведь тебе придется в статике, в C++ тексте, написать что-то вроде:

typedef    TYPELIST_2(
        const std_string&, 
        unsigned int )
    SayThisParamList;
typedef    Loki::Functor< TheObject*, 
        SayThisParamList >
    SayThis;

SayThis m = pClass->GetMethod<void, SayThisParamList >( pObj, "sayThis" );
m();


Но, ведь ты заранее не можешь сам описать вызовы всех методов из всех доступных из скрипта классов. Если бы ты мог, то reflection тебе не потребовался бы.

Или ты по скрипту будешь генерировать C++ код, затем компилировать его в dll, подгружать dll и вызывать оттуда сгенерированную заглушку?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[10]: Reflection for C++
От: yxiie Украина www.enkord.com
Дата: 08.03.05 08:16
Оценка:
Здравствуйте, eao197, Вы писали:

E>А ты можешь, если это не секрет, поделится своими идеями на этот счет? А то я, например, не очень понимаю такую вещь. Вот, допустим, в твоем скрипте есть строки:


E>
E>MyObject my;
E>my.sayThis( "Hello, world!", Color::red );
E>


E>Я не помнимаю, как для такого кода, с помощью решения Batiskaf-а ты сделаешь вызов метода C++ объекта. Ведь тебе придется в статике, в C++ тексте, написать что-то вроде:


...

E>Но, ведь ты заранее не можешь сам описать вызовы всех методов из всех доступных из скрипта классов. Если бы ты мог, то reflection тебе не потребовался бы.


E>Или ты по скрипту будешь генерировать C++ код, затем компилировать его в dll, подгружать dll и вызывать оттуда сгенерированную заглушку?


нет никаких длл. забыл, что у меня первым пунктом стоит портабельность?
как я вызову? просто нужно будет расширить этот код так, чтобы при регистрации метода он еще и добавлял информацию о параметрах метода, таким образом
у нас в ран-тайм будет полная сигнатура метода класса, по которой скрипту не составит труда найти нужный метод.
... << RSDN@Home 1.1.3 stable >>
Re[9]: Reflection for C++
От: Tonal- Россия www.promsoft.ru
Дата: 08.03.05 10:18
Оценка:
Здравствуйте, yxiie, Вы писали:
Y>Тут нужно иметь общую иерархию, с которой можно было сравнительно одинаково удобно работать как на С++ (там где нужна скорость) так и на скрипт-языке (там где скорость не критична). плюс всякие бонусы типа сериализации приветствуются.
По моему тут некоторое противоречие: или скорость выполнения и статический контроль типов, или скорость и прозрачность разработки в скриптовом языке.
Вез жертв тут не обойтись.
Когда я сталкивался с похожей задачей, была реализована отдельная "высокоуровнивая" иерархия специально для скриптования.
Мы её расширяли/изменяли по мере надобности.
Если вдруг обнаруживали часто встречающуюся или недостающую задачу.

Тут ещё играет роль тот фактор, что скрипты часто пишут конечные пользователи, у которых достаточно мало опыта как в написании программ, так и в отладке. А ядро системы всё-таки более квалифицированные програмеры.
Соответственно нужен более "надёжный" и "защищённый" от дурака язык. Понятно, что если одни и те же классы мы попытаемся использовать и там и там, получим либо утяжеление в C++ либо напряги в скрипте.

А как наиболее прозрачное решение можно посоветовать либо всё делать на COM/CORBA, либо взять интерпретатор Cint из Root-а или Виртуальную машину для С++.
... << RSDN@Home 1.1.4 beta 4 rev. 343>>
Re[10]: Reflection for C++
От: yxiie Украина www.enkord.com
Дата: 08.03.05 10:43
Оценка:
Здравствуйте, Tonal-, Вы писали:

T>Здравствуйте, yxiie, Вы писали:

Y>>Тут нужно иметь общую иерархию, с которой можно было сравнительно одинаково удобно работать как на С++ (там где нужна скорость) так и на скрипт-языке (там где скорость не критична). плюс всякие бонусы типа сериализации приветствуются.
T>По моему тут некоторое противоречие: или скорость выполнения и статический контроль типов, или скорость и прозрачность разработки в скриптовом языке.
T>Вез жертв тут не обойтись.
почему же противоречие? когда работаем на С++ имеем скорость и контроль. когда на скриптовом языке — имеем удобность и прозрачность.

T>Когда я сталкивался с похожей задачей, была реализована отдельная "высокоуровнивая" иерархия специально для скриптования.

T>Мы её расширяли/изменяли по мере надобности.
T>Если вдруг обнаруживали часто встречающуюся или недостающую задачу.

у меня щас тоже так, и где я говорил, что я против такого?

T>Тут ещё играет роль тот фактор, что скрипты часто пишут конечные пользователи, у которых достаточно мало опыта как в написании программ, так и в отладке. А ядро системы всё-таки более квалифицированные програмеры.


какой еще фактор? это основная причина, по которой я все это дело затеял.

T>Соответственно нужен более "надёжный" и "защищённый" от дурака язык. Понятно, что если одни и те же классы мы попытаемся использовать и там и там, получим либо утяжеление в C++ либо напряги в скрипте.


скрипт язык будет клоном JavaScript.

T>А как наиболее прозрачное решение можно посоветовать либо всё делать на COM/CORBA,


не портабельно, а это условие номер 1.

T>либо взять интерпретатор Cint из Root-а или Виртуальную машину для С++.


слишком сложный скрипт-язык.
... << RSDN@Home 1.1.3 stable >>
Re[11]: Reflection for C++
От: hth  
Дата: 08.03.05 10:50
Оценка: :))
Здравствуйте, yxiie, Вы писали:


T>>либо взять интерпретатор Cint из Root-а или Виртуальную машину для С++.


Y>слишком сложный скрипт-язык.


C++ — сложный, согласен,
но C — очень простой, какой еще проще?

Если нужна простата — пользуй C!
Re[12]: Reflection for C++
От: yxiie Украина www.enkord.com
Дата: 08.03.05 10:57
Оценка:
Здравствуйте, hth, Вы писали:

T>>>либо взять интерпретатор Cint из Root-а или Виртуальную машину для С++.


Y>>слишком сложный скрипт-язык.


hth>C++ — сложный, согласен,

hth>но C — очень простой,

простой для тебя, для меня, для программиста.
а скрипты предполагается будут писать непрограммисты.

hth>какой еще проще?


я уже сказал — JavaScript. практика использования Macromedia Flash показывает, что дизайнеры могут вполне сносно его использовать (напомню ActionScript из Flash — по сути обрезанный JavaScript)

hth>Если нужна простата — пользуй C!


нет уж спасибо
... << RSDN@Home 1.1.3 stable >>
Re[13]: Reflection for C++
От: hth  
Дата: 08.03.05 11:10
Оценка:
Здравствуйте, yxiie, Вы писали:

Y>Здравствуйте, hth, Вы писали:


T>>>>либо взять интерпретатор Cint из Root-а или Виртуальную машину для С++.


Y>>>слишком сложный скрипт-язык.


hth>>C++ — сложный, согласен,

hth>>но C — очень простой,

Y>простой для тебя, для меня, для программиста.

Y>а скрипты предполагается будут писать непрограммисты.

hth>>какой еще проще?


Y>я уже сказал — JavaScript. практика использования Macromedia Flash показывает, что дизайнеры могут вполне сносно его использовать (напомню ActionScript из Flash — по сути обрезанный JavaScript)


hth>>Если нужна простата — пользуй C!


Y>нет уж спасибо


потушим так любимый ламерами и льюзерами пионерский костер!
Re[11]: Reflection for C++
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 09.03.05 06:14
Оценка:
Здравствуйте, yxiie, Вы писали:

Y>Здравствуйте, eao197, Вы писали:


E>>А ты можешь, если это не секрет, поделится своими идеями на этот счет? А то я, например, не очень понимаю такую вещь. Вот, допустим, в твоем скрипте есть строки:


E>>
E>>MyObject my;
E>>my.sayThis( "Hello, world!", Color::red );
E>>


E>>Я не помнимаю, как для такого кода, с помощью решения Batiskaf-а ты сделаешь вызов метода C++ объекта. Ведь тебе придется в статике, в C++ тексте, написать что-то вроде:


Y>...


E>>Но, ведь ты заранее не можешь сам описать вызовы всех методов из всех доступных из скрипта классов. Если бы ты мог, то reflection тебе не потребовался бы.


E>>Или ты по скрипту будешь генерировать C++ код, затем компилировать его в dll, подгружать dll и вызывать оттуда сгенерированную заглушку?


Y>нет никаких длл. забыл, что у меня первым пунктом стоит портабельность?


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

Y>как я вызову? просто нужно будет расширить этот код так, чтобы при регистрации метода он еще и добавлял информацию о параметрах метода, таким образом


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

Y>у нас в ран-тайм будет полная сигнатура метода класса, по которой скрипту не составит труда найти нужный метод.


Найти-то ладно, мне интересно, что ты дальше делать будешь

Вот пусть у тебя будет метод с сигнатурой void sayThis( const std::string&, unsigned int ). В скрипте у тебя будет два объекта: строка "Hello, World" и константа Color::red. Для того, чтобы хранить значения этих объектов, тебе потребуется иметь два C++ объекта, например класса ScalarExpression. Так вот, мне интересно:

— интерпритатор скрипта умеет работать с элемента скрипта. Он знает, как плодить и работать со ScalarExpression;
— интерпритатор в месте вызова sayThis определяет типы параметров, строит сигнатуру и по ней находит указатель на метод sayThis;
— как дальше должен вести себя интерпритатор, чтобы вызвать метод sayThis?

Ведь, когда интерпритатор компилировался, он ничего не знал про метод sayThis. И в его C++ коде не было конструкции:
void (*sayThisPtr)( const std::string &, unsigned int ) = ...;
(*sayThisPtr)( firstArg.value(), secondArg.value() );


ИМХО, здесь у тебя два варианта:

1. Реализовать возможность вызова метода вручную запихивая параметры в стек и используюя ассемблерную инструкцию call. Но тогда о переносимости можно забыть.

2. Самому делать proxy для вызова методов объектов, например, в виде:
void
sayThisProxy( const std::vector< Expression * > & args, MyObject * object )
    {
        StringScalarExpression * first = dynamic_cast< StringScalarExpression * >( args[ 0 ] );
        UintScalarExpression * second = dynamic_cast< UintScalarExpression * >( args[ 1 ] );
        
        object->sayThis( first, second );
    }


ИМХО, создание таких proxy -- это не есть механизм reflection.

Более того, такие задачи уже были решены в языках типа Ruby, Python, Lua, ... Есть даже проект Swig, который, насколько я его понимаю, значительно упрощает интеграцию скриптовых языков с языками типа C/C++, C#, Java. Может тебе в ту сторону посмотреть?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[12]: Reflection for C++
От: yxiie Украина www.enkord.com
Дата: 09.03.05 08:06
Оценка:
Здравствуйте, eao197, Вы писали:

E>>>Или ты по скрипту будешь генерировать C++ код, затем компилировать его в dll, подгружать dll и вызывать оттуда сгенерированную заглушку?


Y>>нет никаких длл. забыл, что у меня первым пунктом стоит портабельность?


E>Нет, не забыл. Но перечисли, пожалуйста, платформы, на которых предполагается использовать твою систему, и на которой не будет DLL


любая игровая консоль...

Y>>как я вызову? просто нужно будет расширить этот код так, чтобы при регистрации метода он еще и добавлял информацию о параметрах метода, таким образом


E>O! Т.е., задача на самом деле сужается. Т.е. у тебя есть необходимость вызывать из скрипта методы не всех объектов, а только специально предназначенных для этого. Далее выяснится, что и у этих объектов нужно вызывать не все методы. Или я не прав?


ну да. вызывать нужно только зарегистрированные методы зарегистрированных объектов.

Y>>у нас в ран-тайм будет полная сигнатура метода класса, по которой скрипту не составит труда найти нужный метод.


E>Найти-то ладно, мне интересно, что ты дальше делать будешь


E>Вот пусть у тебя будет метод с сигнатурой void sayThis( const std::string&, unsigned int ). В скрипте у тебя будет два объекта: строка "Hello, World" и константа Color::red. Для того, чтобы хранить значения этих объектов, тебе потребуется иметь два C++ объекта, например класса ScalarExpression. Так вот, мне интересно:


E>- интерпритатор скрипта умеет работать с элемента скрипта. Он знает, как плодить и работать со ScalarExpression;

E>- интерпритатор в месте вызова sayThis определяет типы параметров, строит сигнатуру и по ней находит указатель на метод sayThis;
E>- как дальше должен вести себя интерпритатор, чтобы вызвать метод sayThis?

E>Ведь, когда интерпритатор компилировался, он ничего не знал про метод sayThis. И в его C++ коде не было конструкции:

E>
E>void (*sayThisPtr)( const std::string &, unsigned int ) = ...;
E>(*sayThisPtr)( firstArg.value(), secondArg.value() );
E>


E>ИМХО, здесь у тебя два варианта:


E>1. Реализовать возможность вызова метода вручную запихивая параметры в стек и используюя ассемблерную инструкцию call. Но тогда о переносимости можно забыть.


E>2. Самому делать proxy для вызова методов объектов, например, в виде:

E>
E>void
E>sayThisProxy( const std::vector< Expression * > & args, MyObject * object )
E>    {
E>        StringScalarExpression * first = dynamic_cast< StringScalarExpression * >( args[ 0 ] );
E>        UintScalarExpression * second = dynamic_cast< UintScalarExpression * >( args[ 1 ] );
        
E>        object->sayThis( first, second );
E>    }
E>


да, скорее всего второй вариант, только зачем самому делать прокси? у байндера к методу будет ф-ция, которая будет
принимать параметры скрипта и на основе их формировать вызов С++ метода.

E>ИМХО, создание таких proxy -- это не есть механизм reflection.


не понял, объясни, что ты хочешь сказать.

E>Более того, такие задачи уже были решены в языках типа Ruby, Python, Lua, ...


такие, да, но не все. по сути либы типа boost.python делают только байнд. мне же скорее нужно что-то среднее между байндом и полноценной рефлексией.

E>Есть даже проект Swig, который, насколько я его понимаю, значительно упрощает интеграцию скриптовых языков с языками типа C/C++, C#, Java. Может тебе в ту сторону посмотреть?


щас посмотрю, не помню, может проморгал его...
... << RSDN@Home 1.1.3 stable >>
Re[13]: Reflection for C++
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 09.03.05 08:14
Оценка:
Здравствуйте, yxiie, Вы писали:

Y>Здравствуйте, eao197, Вы писали:


E>>>>Или ты по скрипту будешь генерировать C++ код, затем компилировать его в dll, подгружать dll и вызывать оттуда сгенерированную заглушку?


Y>>>нет никаких длл. забыл, что у меня первым пунктом стоит портабельность?


E>>Нет, не забыл. Но перечисли, пожалуйста, платформы, на которых предполагается использовать твою систему, и на которой не будет DLL


Y>любая игровая консоль...


Ну не любая
На XBox, например, Windows стоит. Там DLL-ки точно есть
А под какими OS, например, Sony PS работает, я не знаю.

<...>

E>>2. Самому делать proxy для вызова методов объектов, например, в виде:

E>>
E>>void
E>>sayThisProxy( const std::vector< Expression * > & args, MyObject * object )
E>>    {
E>>        StringScalarExpression * first = dynamic_cast< StringScalarExpression * >( args[ 0 ] );
E>>        UintScalarExpression * second = dynamic_cast< UintScalarExpression * >( args[ 1 ] );
        
E>>        object->sayThis( first, second );
E>>    }
E>>


Y>да, скорее всего второй вариант, только зачем самому делать прокси? у байндера к методу будет ф-ция, которая будет

Y>принимать параметры скрипта и на основе их формировать вызов С++ метода.

Но как делать вызов? Мне просто интересно код такого байндера увидеть.

E>>ИМХО, создание таких proxy -- это не есть механизм reflection.


Y>не понял, объясни, что ты хочешь сказать.


Ok. Но мне нужно некоторое время, чтобы восстановить в памяти информацию по reflection в Java. Тогда попробую объяснить.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[14]: Reflection for C++
От: yxiie Украина www.enkord.com
Дата: 09.03.05 08:27
Оценка:
Здравствуйте, eao197, Вы писали:

Y>>любая игровая консоль...


E>Ну не любая

E>На XBox, например, Windows стоит. Там DLL-ки точно есть

на Xbox как раз точно нет, насчет остальных точно не скажу.

E>А под какими OS, например, Sony PS работает, я не знаю.


Sony Playstation 2 OS = Sony Linux
Nintendo GameCube OS = Dolphin Mac OS какая-то

Y>>да, скорее всего второй вариант, только зачем самому делать прокси? у байндера к методу будет ф-ция, которая будет

Y>>принимать параметры скрипта и на основе их формировать вызов С++ метода.

E>Но как делать вызов? Мне просто интересно код такого байндера увидеть.


ну дак посмотри у Batiskaf-a там же все открыто, или я не понял, что именно ты хочешь увидеть?
... << RSDN@Home 1.1.3 stable >>
Re[15]: Reflection for C++
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 09.03.05 08:33
Оценка:
Здравствуйте, yxiie, Вы писали:

Y>Здравствуйте, eao197, Вы писали:


Y>>>любая игровая консоль...


E>>Ну не любая

E>>На XBox, например, Windows стоит. Там DLL-ки точно есть

Y>на Xbox как раз точно нет, насчет остальных точно не скажу.


Windows без DLL?
Век живи, век учись. А где про это прочитать можно?

E>>А под какими OS, например, Sony PS работает, я не знаю.


Y>Sony Playstation 2 OS = Sony Linux


Ну под Linux-ом-то DLL-ки точно должны быть.

Y>Nintendo GameCube OS = Dolphin Mac OS какая-то


Y>>>да, скорее всего второй вариант, только зачем самому делать прокси? у байндера к методу будет ф-ция, которая будет

Y>>>принимать параметры скрипта и на основе их формировать вызов С++ метода.

E>>Но как делать вызов? Мне просто интересно код такого байндера увидеть.


Y>ну дак посмотри у Batiskaf-a там же все открыто, или я не понял, что именно ты хочешь увидеть?


yxiie, я же уже спрашивал раньше. Мне интересно, как появится такой код:
typedef    TYPELIST_2(
        const std_string&, 
        unsigned int )
    SayThisParamList;
typedef    Loki::Functor< TheObject*, 
        SayThisParamList >
    SayThis;

SayThis m = pClass->GetMethod<void, SayThisParamList >( pObj, "sayThis" );
m();


Его что, ручками нужно написать?
Для каждого метода, который можно вызывать из скрипта?

Кстати, из скрипта ведь можно будет не все C++ объекты инстанциировать? А только специально для этого предназначенные.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[16]: Reflection for C++
От: yxiie Украина www.enkord.com
Дата: 09.03.05 08:41
Оценка:
Здравствуйте, eao197, Вы писали:

Y>>на Xbox как раз точно нет, насчет остальных точно не скажу.


E>Windows без DLL?

E>Век живи, век учись. А где про это прочитать можно?

набери в гугле что-то типа xbox development, в любом описании характеристик Xbox все должно быть.

E>>>А под какими OS, например, Sony PS работает, я не знаю.


Y>>Sony Playstation 2 OS = Sony Linux


E>Ну под Linux-ом-то DLL-ки точно должны быть.


совсем не обязательно. PlayStation 2 по техническим характеристикам хуже Xbox, а если в первой такого не,
то и тут скорее такая же фигня. да и незачем это на консолях.

Y>>ну дак посмотри у Batiskaf-a там же все открыто, или я не понял, что именно ты хочешь увидеть?


E>yxiie, я же уже спрашивал раньше. Мне интересно, как появится такой код:

E>
E>typedef    TYPELIST_2(
E>        const std_string&, 
E>        unsigned int )
E>    SayThisParamList;
E>typedef    Loki::Functor< TheObject*, 
E>        SayThisParamList >
E>    SayThis;

E>SayThis m = pClass->GetMethod<void, SayThisParamList >( pObj, "sayThis" );
E>m();
E>


E>Его что, ручками нужно написать?

E>Для каждого метода, который можно вызывать из скрипта?

а зачем такой код? такой код будет использоваться только в С++, для скрипта будет скорее что-то типа

BindedMethod->Invoke(obj, params);

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


те, которые зарегистрированы, да.
... << RSDN@Home 1.1.3 stable >>
Re[17]: Reflection for C++
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 09.03.05 08:49
Оценка:
Здравствуйте, yxiie, Вы писали:

E>>yxiie, я же уже спрашивал раньше. Мне интересно, как появится такой код:

E>>
E>>typedef    TYPELIST_2(
E>>        const std_string&, 
E>>        unsigned int )
E>>    SayThisParamList;
E>>typedef    Loki::Functor< TheObject*, 
E>>        SayThisParamList >
E>>    SayThis;

E>>SayThis m = pClass->GetMethod<void, SayThisParamList >( pObj, "sayThis" );
E>>m();
E>>


E>>Его что, ручками нужно написать?

E>>Для каждого метода, который можно вызывать из скрипта?

Y>а зачем такой код? такой код будет использоваться только в С++, для скрипта будет скорее что-то типа


Y>BindedMethod->Invoke(obj, params);


Так вот и я об этом же. Что из скрипта будет вызываться некий Invoke, а уже в Invoke будет код, который приведен выше. Так?

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


Y>те, которые зарегистрированы, да.


Так вот, если объекты, которые ты делаешь доступными для скрипта и методы этих объектов заранее определены, то зачем огород с reflection?

Почему просто не сделать BindedMethod->Invoke оберткой сразу над конкретным C++ классом/интерфейсом? А уже нужные тебе C++ классы/интерфейсы инстанциировать посредством фабрики?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[18]: Reflection for C++
От: yxiie Украина www.enkord.com
Дата: 09.03.05 09:09
Оценка:
Здравствуйте, eao197, Вы писали:

E>Здравствуйте, yxiie, Вы писали:


E>>>yxiie, я же уже спрашивал раньше. Мне интересно, как появится такой код:

E>>>
E>>>typedef    TYPELIST_2(
E>>>        const std_string&, 
E>>>        unsigned int )
E>>>    SayThisParamList;
E>>>typedef    Loki::Functor< TheObject*, 
E>>>        SayThisParamList >
E>>>    SayThis;

E>>>SayThis m = pClass->GetMethod<void, SayThisParamList >( pObj, "sayThis" );
E>>>m();
E>>>


E>>>Его что, ручками нужно написать?

E>>>Для каждого метода, который можно вызывать из скрипта?

Y>>а зачем такой код? такой код будет использоваться только в С++, для скрипта будет скорее что-то типа


Y>>BindedMethod->Invoke(obj, params);


E>Так вот и я об этом же. Что из скрипта будет вызываться некий Invoke, а уже в Invoke будет код, который приведен выше. Так?


зачем? в байнд-объекте мы уже имеем адрес метода и информацию о параметрах. единственное, что нужно — обработать и преобразовать переданные
скриптом параметры в подходящие для этого метода и сделать вызов.

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


Y>>те, которые зарегистрированы, да.


E>Так вот, если объекты, которые ты делаешь доступными для скрипта и методы этих объектов заранее определены, то зачем огород с reflection?


E>Почему просто не сделать BindedMethod->Invoke оберткой сразу над конкретным C++ классом/интерфейсом? А уже нужные тебе C++ классы/интерфейсы инстанциировать посредством фабрики?


потому, что если мы обойдемся только байндом, то из скрипта мы сможем оперировать объектами С++, а из С++ оперировать объектами скрипта — нет.
... << RSDN@Home 1.1.3 stable >>