从提升通话崩溃::蟒蛇:: EXEC(任何) [英] Crash on call from boost::python::exec( anything )

查看:166
本文介绍了从提升通话崩溃::蟒蛇:: EXEC(任何)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现一些Python的东西进入我的计划,我已经决定使用升压:: Python的,所以我按照说明编译它,用的bjam,使用的MinGW / GCC,越来越DLL和.a文件结果
我使用code ::这个模块,所以我把DLL文件在我的项目的工作目录中,其中的dll我用剩下的都是,并决定运行升压: :蟒蛇:: EXEC(b = 5); 结果
我立刻得到一个崩溃。想法?搜索结果

I'm trying to implement some Python stuff into my program and I've decided to use Boost::Python, so I compiled it according to the instructions, with bjam, using mingw/gcc, getting dlls and .a files
I'm using Code::Blocks for this, so I've put the dlls in the working directory of my project, where the rest of dlls I use are, and decided to run boost::python::exec("b = 5");
Instantly I get a crash. Ideas?

#include <boost/python.hpp>

float func(int a)
{
  return a*a-0.5;
}

BOOST_PYTHON_MODULE(test_module)
{
  using namespace boost::python;
  def("func", func);
}

int main()
{
  //Try one
  boost::python::exec("b = 5");
  //Crash

  //Try two
  Py_Initialize();
  boost::python::exec("b = 5");
  //Works fine

  //Try three
  Py_Initialize();
  boost::python::exec("import test_module");
  //Throws boost::python::error_already_set and crashes

  /*
    Something along the lines of
    boost::python::exec("import test_module\n"
                        "var = test_module.func( 3 )\n");
  */    
}

在我的项目的编译选项部分,我已经添加了 libboost_python3-mgw48-D-1_54.dll libpython33 被链接所以它会编译。结果
想法?

Under the build options section of my project, I've added libboost_python3-mgw48-d-1_54.dll and libpython33 to be linked so it'd compile.
Ideas?

推荐答案

当嵌入Python时,几乎是除preTER已经用的 Py_Initialize() 。试图初始化之前调用间preTER,如的boost ::蟒蛇:: EXEC(),将导致不确定的行为。

When embedding Python, almost all calls to Python or Boost.Python should occur after the interpreter has been initialized with Py_Initialize(). Trying to invoke the interpreter before initialization, such as with boost::python::exec(), will result in undefined behavior.

虽然标识崩溃的根源,也有一些微妙的细节,以获得完成嵌入Python和模块的最终目标,然后让 EXEC 导入嵌入式模块。

While that identifies the source of the crash, there are some subtle details to obtain the accomplish the final goal of embedding Python and a module, then have exec import the embedded module.


  • 当导入模块,Python会首先检查模块是内置模块。如果该模块不是内置组件,然后Python将尝试加载基于模块名称的库,并期望库,以提供将初始化模块的功能。由于 test_module 被嵌入,它的初始化需要明确添加,这样的内置搜索时导入可以找到它-in模块。

  • 导入语句使用 __ __进口功能。此功能需要可用 EXEC 的全局范围内。

  • When importing a module, Python will first check if the module is a built-in module. If the module is not a built-in module, then Python will try to load a library based on the module name, and expects the library to provide a function that will initialize the module. As the test_module is being embedded, its initialization needs to be explicitly added so that import can find it when searching for built-in modules.
  • The import statement uses the __import__ function. This function needs to be available within exec's globals.

下面是一个完整的例子演示了如何做到这一点:

Here is a complete example demonstrating how to accomplish this:

#include <boost/python.hpp>

float func(int a)
{
  return a*a-0.5;
}

BOOST_PYTHON_MODULE(test_module)
{
  using namespace boost::python;
  def("func", func);
}

// Use macros to account for changes in Python 2 and 3:
// - Python's C API for embedding requires different naming conventions for
//   module initialization functions.
// - The builtins module was renamed.
#if PY_VERSION_HEX >= 0x03000000
#  define MODULE_INIT_FN(name) BOOST_PP_CAT(PyInit_, name)
#  define PYTHON_BUILTINS "builtins"
#else
#  define MODULE_INIT_FN(name) BOOST_PP_CAT(init, name)
#  define PYTHON_BUILTINS "__builtin__"
#endif

int main()
{
  // Add the test_module module to the list of built-in modules.  This
  // allows it to be imported with 'import test_module'.
  PyImport_AppendInittab("test_module", &MODULE_INIT_FN(test_module));

  Py_Initialize();

  namespace python = boost::python;
  try
  {
    // Create an empty dictionary that will function as a namespace.
    python::dict ns;

    // The 'import' statement depends on the __import__ function.  Thus,
    // to enable 'import' to function the context of 'exec', the builtins
    // module needs to be within the namespace being used.
    ns["__builtins__"] = python::import(PYTHON_BUILTINS);

    // Execute code.  Modifications to variables will be reflected in
    // the ns.
    python::exec("b = 5", ns);

    std::cout << "b is " << python::extract<int>(ns["b"]) << std::endl;

    // Execute code using the built-in test_module.
    python::exec(
      "import test_module\n"
      "var = test_module.func(b)\n",
      ns);

    std::cout << "var is " << python::extract<float>(ns["var"]) << std::endl;
  }
  catch (python::error_already_set&)
  {
    PyErr_Print();
  }
}

当执行时,它的输出是:

When executed, its output is:

b is 5
var is 24.5

这篇关于从提升通话崩溃::蟒蛇:: EXEC(任何)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆