Форум сайта python.su
Все оказалось гораздо проще :)
locals = bp::ptr(this);
Андрей, снова большое спасибо за помощь!
Офлайн
Пожалуйста. Но это - тупик, поверьте. Я пробовал, знаю…
Правильный способ такой: заворачиваете в питон инициализацию, главный цикл и финализацию. Заворачиваете игровые объекты. Запускаете все из питона, а не из С++.
Офлайн
Тогда ведь получится, что половина всего функционала игрового сервера будет выполняться питоном. А моя задача просто обработчик скриптов приделать. Я просто напишу (или попрошу коллег написать) удобоваримые для питона методы на с++, чтобы избежать проблем с объектами, и буду их вызывать. Тогда получится что-то типа функционально ориентированного апи для скриптов, что я изначально и хотел.
В любом случае, пока моих знаний хватило с вашей помощью только для этого, потом по мере их роста буду что-то улучшать.
Офлайн
Делайте, как считаете нужным. А я расскажу одну небольшую историю.
Довольно давно нам тоже нужно было добавить скрипты в программу, разрабатывамую на С++.
Большого опыта в этом деле не было и решили сделать все как можно проще.
Инициализировали питон, завернули несколько классов через boost и научили их вызывать питоновский код, указывая имя модуля и функции в нем.
Считалось, что простого процедурного подхода хватит с головой, да и Питон - мощный язык, как-нибудь выкрутимся.
Сначала все шло неплохо, подключилось все за несколько дней и примитивные скрипты заработали, радуя глаз и грея душу.
Потом, как водится, начались проблемы.
Объем скриптов рос, увеличивалась их сложность. Оставаться в процедурных рамках было все труднее, тем более Питон - объектно-ориентированный язык, да и С++ тоже. Плюс у всех разработчиков объектное мышление уже прочно поселилось в головах.
Так появились скриптовые классы. Следующая проблема - эти классы нужно где-то хранить. Создавать экземпляры только на время вызова callback, успешно забывая о них сразу же после завершения функции - неудобно. Естественно, начали интенсивно использовать глобальные объекты (ни к чему хорошему это не привело).
Потом у С++ объектов появился bp::object slot, в который можно было что-нибудь записать. Естественно, одним объектом ограничиваться не захотелось, и в слоте стали появляться списки и словари, содержащие наши комплексные Питоновские объекты.
Код постепенно утрачивал все признаки читабельности, количество классов росло и увеличивалась их сложность, сопровождение и отладка стали кошмаром и изощренной разновидностью мазохизма. О тестировании не говорю просто потому, что у нас его не было (в те времена усиленно читал Кента Бека и никак не мог понять, как применить его увлекательные книги к моему реальному коду).
Переписать все наново не поднималась рука, да и времени не было - нужно выдавать новые фичи, а не поломать проект на месяц-другой - чтобы потом получить то же самое, только чуть-чуть не рабочее. Теперь мне кажется, что все-таки следовало решиться на этот неприятный шаг - и чем раньше, тем лучше.
Максимум, к чему мы пришли - в slot стали стараться ложить Питоновский объект - двойник С++. Взаимодействие между ними вышло довольно запутанным (а ведь по дизайну это единый объект, Питон должен просто наследовать С++ класс). Кода - больше, чем нужно (и это на весьма лаконичном Питоне).
Проект дотянули до финиша и отдали заказчику.
А потом довольно скоро пришлось делать очень похожую штуку. Только спроектировали мы ее уже правильно - и наглядно почувствовали разницу. Теперь я знаю, как следует осуществлять склейку Питона и С++ - и как не нужно это делать никогда.
Офлайн
То есть вы предлагаете сделать просто биндинг для библиотеки на с++, и все писать на питоне с использованием этого модуля? Я хотел так сделать изначально, но тогда на меня ложиться большая ответственность и много работы, а мне хотелось приделать простой скриптовый движок. Жалко, использовать его в полевых условиях не удалось, и по граблям я не походил ;)
П.С: К сожалению, проект развалился, как бывает с подобными кустарными проектами с удаленными участниками. Тем не менее, опыт был получен :)
Офлайн
Большую часть кода писать можно и на С++ - не проблема. На питоне можно делать только скриптовую часть, если хочется (уверен, аппетит прийдет во время еды).
Правило первое: если объект виден в Питоне, его время жизни должно этим же Питоном управляться. Его можно нарушать, только полностью отдавая себе отчет о последствиях, и очень не часто. Создавать в Питоне, и в нем же уничтожать. Можно через Python C API или boost::python - главное, чтобы объект жил столько, сколько ему Питон скажет. Просто потому, что у него есть garbage collector, а у C++ - нет. Если бы был - пришлось бы делать так, чтобы объект находился в обоих одновременно. python.net так и поступает.
Правило второе, специфичное: если у вас есть объект NPC, то скриптующий код помещайте в класс-наследник. Это - естественное проектирование. Ведь если бы у вас скрипты писались на С++, наверное делали бы плюсовых наследников. А так - питоновские. Разницы особой нет. Отступление от правила легко ведет к каше в голове и отвратительному дизайну.
А все остальное можно делать на плюсах. И высветить несколько (по пальцам пересчитать) простых функций.
Офлайн