0

使用 boost python,我向我的 python 包装器添加了一个属性,其中值来自枚举类型,例如:

scope().attr("myconstant")=some_namespace::some_class::some_enum_value;

但是当我导入我的 python 模块时出现运行时错误:

terminate called after throwing an instance of 'boost::python::error_already_set'

在其他线程之后,我将上面的内容放在 try/catch 中,但没有捕获任何可以调用 PyErr_Fetch 的内容。我仍然很好奇原始 python 错误发生在哪里。

事实证明我必须做

scope().attr("myconstant")=int(some_namespace::some_class::some_enum_value);

然后它运行。

另一个但我认为相关的问题是,如果您在返回 C++ 枚举的 Python 包装器中导出 C++ 函数,但您不导出该枚举,那么一切都很好,直到您从 python 调用此函数。然后 boost 生成一个关于找不到类型的 python 异常。

很明显,boost 是在运行时做一些看起来(在我看来)应该在编译时完成的事情。这两个问题的诊断都非常耗时。有谁知道发生了什么?在运行时发生的事情比我预期的要多,如果我直接使用 python 扩展 API,我会遇到 boost python 的性能问题吗?除了性能之外,我担心 boost python 代码有更多的错误,直到运行时才会发现,然后直接 python 扩展代码会有。

另一方面,所有这些动态类型绑定是否有很大的收获?显然有用于编写我自己的 python 扩展的不错的 boost 接口——但是所有这些动态绑定是否更容易将新的 boost python 包装器添加到现有系统中,然后直接用 python 扩展 API 编写包装器?

4

1 回答 1

1

由于 Python 支持动态名称解析,我想 Boost.python 执行编译时断言会相当困难并且会妨碍用户。C++ 代码在运行时暴露给 Python,并且 Boost.Python 类型转换可能已在不同的模块中注册,在运行时单独加载。

Boost.Python,甚至 Python C-API,在运行时执行大部分工作。与 Python C-API 相比,Boost.Python 不会再将错误延迟到运行时。当 Python 导入 Boost.Python 模块时,BOOST_PYTHON_MODULE代码会执行、创建类型、注册类型标识和注册函数,以实现 Python 和 C++ 对象之间的无缝互操作性。总体而言,C-API 或任何其他 Python 语言绑定工具集仍需要相同的设置过程。由于 Boost.Python 提供了一种高级通用解决方案,因此与为应用程序量身定制的手写绑定相比,可以预期它会更加臃肿。

我个人的经验是,使用 Boost.Python 扩展现有系统比直接写入 Python C-API 更容易。我必须编写更少的代码,从而减少错误,同时提高可读性和可维护性。例如,考虑官方的 Python Extending Simple Example

#include <stdlib.h> // system
#include <Python.h>

static PyObject*
spam_system(PyObject* self, PyObject* args)
{
  const char* command;
  if (!PyArg_ParseTuple(args, "s", &command))
    return NULL;
  return Py_BuildValue("i", system(command));
}

static PyMethodDef SpamMethods[] =
{
  {"system", &spam_system, METH_VARARGS,
   "Execute a shell command."},
  {NULL, NULL, 0, NULL} /* Sentinel */
};

PyMODINIT_FUNC
initspam(void)
{
  Py_InitModule("spam", SpamMethods);
}

和 Boost.Python 中的等价物:

#include <stdlib.h> // system
#include <boost/python.hpp>

BOOST_PYTHON_MODULE(spam)
{
  boost::python::def("system", &system);
}
于 2013-07-17T16:42:17.203 回答