Призовая игра с встраиванием питона
Jul. 28th, 2022 10:51 pmЯ не возьмусь определять что мне более отвратительно libboost или python. Но право скажу собранные вместе в boost::python они производят на свет субстанцию непревзойденного свойства.
#include <boost/python.hpp> #include <stdio.h> int main() { Py_InitializeEx(0); boost::python::object modMath = boost::python::import("math"); boost::python::object cosFunc = modMath.attr("cos"); Py_Finalize(); }
С 2.7м питоном работает нормально, с третьем падает с невнятной ошибкой при отработке хуков при выходе...
Историю с локализацией места проблемы в портируемой программе с последующим вынесением в приведенный standalone, я опущу из-за малосодержательности и нецензурности... Скажу только, что gdb плюс правильно выбранные места для breakpoint'ов рулят.
Далее в процессе плясок вокруг этого примера вдруг обнаруживаю что вот так не падает:
int main() { Py_InitializeEx(0); { boost::python::object modMath = boost::python::import("math"); boost::python::object cosFunc = modMath.attr("cos"); } Py_Finalize(); }
Ага! думаю я. Оно позвало деструктор до финалайза а не после и все перестало падать... Надо сделать так же!
Но вот проблема... аналог переменной cosFunc в портируемой программе глобальная... Создается пустая, а потом после инициалайза заполняется. Можно было бы раскинуть мозгами, как запихнуть туда указатель вместо самого объекта, и сказать ему в нужный момент delete. Но менять весь остальной код очень не хотелось...
А нельзя ли так, чтобы для сложного объекта вызвался деструктор а сам объект опять заполнить пустым значением?
Оказывается можно:
int main() { Py_InitializeEx(0); boost::python::object cosFunc; { boost::python::object modMath = boost::python::import("math"); cosFunc = modMath.attr("cos"); } cosFunc = boost::python::object(); Py_Finalize(); }
оно заменяет сложное значение cosFunc
тривиальным, при этом для заменяемого значения вызывается деструктор.
И вот так -- тоже не падает...
P.S. Отдельно доставила рекомендация документации на 1.55 boost::python просто не вызывать Py_Finalize()
, типа не надо вам это.
P.P.S. Пришел к мысли что сам питон не падает только потому что и так ползает. And you should not boost it.
P.P.P.S. Честно говоря не верил, что осилю с этим разобраться. Без знания, что буста, что питона... Ан нет, получилось...