Инициализация Python - PullRequest
       18

Инициализация Python

5 голосов
/ 14 марта 2011

Я создаю приложение с boost.python. У меня есть какой-то одноэлементный класс с именем ScriptsManager, у него есть функция initPython, которая делает:

mMainModule = bp::import("__main__");
mMainNamespace = bp::import("__dict__");

bp::object ignored = bp::exec("hello = file('hello.txt', 'w')\n"
                  "hello.write('Hello world!')\n"
                  "hello.close()", mMainNamespace);

оба mMainModule, mMainNamespace являются boost::python::object.

Итак, когда я запускаю приложение, я получаю:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) bt
#0  0x0000000000000000 in ?? ()
#1  0x00007ffff5d5efd9 in PyEval_GetGlobals () from /usr/lib/libpython2.7.so.1.0
#2  0x00007ffff5d79113 in PyImport_Import () from /usr/lib/libpython2.7.so.1.0
#3  0x00007ffff5d7935c in PyImport_ImportModule () from /usr/lib/libpython2.7.so.1.0
#4  0x00007ffff5a6d8bd in boost::python::import(boost::python::str) () from /usr/lib/libboost_python.so.1.46.0
#5  0x0000000000510b1b in ScriptsManager::initPython (this=0x7b6850) at /home/ockonal/Workspace/Themisto/src/Core/ScriptsManager.cpp:24
#6  0x0000000000547650 in Application::main (args=...) at /home/ockonal/Workspace/Themisto/src/main.cpp:60
#7  0x00007ffff4ebbf86 in main () from /usr/lib/libclan22App-2.2.so.1
#8  0x00007ffff24c4dcd in __libc_start_main () from /lib/libc.so.6
#9  0x00000000004c9769 in _start ()

Что здесь может быть не так?


UPD1

Когда я звоню Py_Initialize() до bp::import, я получаю:

завершить вызов после броска экземпляр 'Повышение :: питона :: error_already_set'


UPD2

Кажется, что проблема была в коде:

mMainNamespace = bp::import("__dict__");

Код результата:

Py_Initialize();
mMainModule = bp::import("__main__");
mMainNamespace = mMainModule.attr("__dict__");

Я не уверен, что это правильно.


UPD3

Да, 2 -и обновление работает. Так странно, mMainNamespace = bp::import("__dict__") написано в официальных документах для буста.

1 Ответ

3 голосов
/ 14 марта 2011

Я думаю, что вы хотите следующее:

int main (int argc, char** argv)
{
    try
    {
        // If you're going to use threads: PyEval_InitThreads();
        Py_Initialize();
        PySys_SetArgv(argc, argv);

        bp::object mMainModule = bp::import('__main__');
        bp::object mMainNamespace = mMainModule.attr('__dict__');

        bp::object ignored = bp::exec("hello = file('hello.txt', 'w')\n"
              "hello.write('Hello world!')\n"
              "hello.close()", mMainNamespace);
   }
   catch (bp::error_already_set const&)
   {
        PyErr_Print();
   }
}

Py_Initialize() необходимо, try { ... } catch () { ... } -блок выдает сообщение об ошибке Python, подобное тому, которое вы получите от интерпретатора, и bp::import работает только для модулей, а не для атрибутов импортированных модулей: -)

...