Python 初始化段错误
我正在用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 ()
这可能出什么问题呢?
更新1
当我在 bp::import
之前调用 Py_Initialize()
时,我得到了:
终止调用,抛出了一个 实例 'boost::python::error_already_set'
更新2
看起来问题出在这段代码:
mMainNamespace = bp::import("__dict__");
结果代码是:
Py_Initialize();
mMainModule = bp::import("__main__");
mMainNamespace = mMainModule.attr("__dict__");
我不确定这样做是否正确。
更新3
没错,第二次更新有效。真奇怪, mMainNamespace = bp::import("__dict__")
这段代码在官方的boost文档里有写。
1 个回答
3
我觉得你想要的是这个:
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
只适用于模块,不适用于导入模块的属性 :-)