我正在尝试编写一些包装类或函数,它允许我在包装函数之前和之后执行一些代码.
float foo(int x, float y)
{
return x * y;
}
BOOST_PYTHON_MODULE(test)
{
boost::python::def("foo", <somehow wrap "&foo">);
}
Run Code Online (Sandbox Code Playgroud)
理想情况下,包装器应该是通用的,适用于函数和成员函数,具有任何签名.
更多信息:
我正在寻找一种简单的方法来释放/重新获取围绕我昂贵的C++调用的GIL,而无需手动编写像这样的瘦包装器:
float foo_wrapper(int x, float y)
{
Py_BEGIN_ALLOW_THREADS
int result = foo(x, y);
Py_END_ALLOW_THREADS
return result;
}
BOOST_PYTHON_MODULE(test)
{
boost::python::def("foo", &foo_wrapper);
}
Run Code Online (Sandbox Code Playgroud)
对于所有类型的函数,这种包装器将重复多次,我想找到一个允许我避免编码所有函数的解决方案.
我尝试了一些方法,但我能提供的最好的方法是要求用户明确说明返回值和参数的类型,例如:
boost::python::def("foo", &wrap_gil<float, int, float>(&foo_wrapper));
Run Code Online (Sandbox Code Playgroud)
但在我看来应该可以只是将指针传递给函数(&foo_wrapper)并让编译器找出类型.
有谁知道我可以使用的技术或指向正确的方向?
干杯!
我有一堆用C++编写的类和API,并在Boost.Python的帮助下暴露给Python
我目前正在研究创建以下架构的可能性.
在python中:
from boostPythonModule import *
AddFunction( boostPythonObject.Method1, args )
AddFunction( boostPythonObject.Method2, args )
AddFunction( boostPythonObject.Method2, args )
RunAll( ) # running is done by C++
Run Code Online (Sandbox Code Playgroud)
在C++中:
void AddFunction( boost::object method, boost::object args )
{
/// 1. Here i need to extract a real pointer to a function
/// 2. Make argument and type checking for a function under method
/// 3. Unpack all arguments to native types
/// 4. Store the pointer to a function somewhere in local …Run Code Online (Sandbox Code Playgroud) 我用C++编写,我正在创建使用Boost.Python的一个Python包装一个简单的库.有些功能需要很长的时间来执行(超过30秒),我想使它中断,这样,当我按ctrl-d引发一个KeyboardInterrupt在Python解释器,我不知怎么能说++响应的温度.
有没有办法做到这一点?我在boost.org或python.org上找不到有关中断和boost.python的任何信息.
用于将特定C++异常转换为python的当前boost :: python示例如下所示:
void translate (const MyException& e) {
PyErr_SetString(PyExc_RuntimeError, e.what());
}
boost::python::register_exception_translator<MyException>(translate);
Run Code Online (Sandbox Code Playgroud)
不幸的是,这要求我们为每个异常编写一个特定的函数.我们试图通过编写通用异常转换器来简化这一过程:
#include <boost/python.hpp>
// Generalized exception translator for Boost Python
template <typename T> struct GeneralizedTranslator {
public:
void operator()(const T& cxx_except) const {
PyErr_SetString(m_py_except, cxx_except.what());
}
GeneralizedTranslator(PyObject* py_except): m_py_except(py_except) {
boost::python::register_exception_translator<T>(this);
}
GeneralizedTranslator(const GeneralizedTranslator& other): m_py_except(other.m_py_except) {
//attention: do not re-register the translator!
}
private:
PyObject* m_py_except;
};
//allows for a simple translation declaration, removes scope problem
template <typename T> void translate(PyObject* e) {
ExceptionTranslator<T> my_translator(e);
} …Run Code Online (Sandbox Code Playgroud) ANSWERED
好的,我解决了这个问题.它是如何初始化线程状态的.您根本不需要使用ReleaseLock.只需将InitThreads调用添加到模块定义中:
BOOST_PYTHON_MODULE(ModuleName)
{
PyEval_InitThreads();
...
}
Run Code Online (Sandbox Code Playgroud)
好吧,我已经尝试了几个小时来诊断这个问题并且倾注了网络上的每个例子.现在累了所以我可能会遗漏一些明显的东西,但这里发生了什么:
我在boost python中包装一个库.我正在运行一个python脚本,它导入lib,构造一些对象,然后从c ++接收回调到python的回调.在我调用任何python函数之前,我尝试获取全局解释器锁.以下是一些示例代码:
class ScopedGILRelease
{
public:
inline ScopedGILRelease()
{
d_gstate = PyGILState_Ensure();
}
inline ~ScopedGILRelease()
{
PyGILState_Release(d_gstate);
}
private:
PyGILState_STATE d_gstate;
};
class PyTarget : public DingoClient::ClientRequest::Target, public wrapper<DingoClient::ClientRequest::Target>
{
public:
PyTarget(PyObject* self_) : self(self_) {}
~PyTarget() {
ScopedGILRelease gil_lock;
}
PyObject* self;
void onData(const boost::shared_ptr<Datum>::P & data, const void * closure)
{
ScopedGILRelease gil_lock;
// invoke call_method to python
}
...
}
Run Code Online (Sandbox Code Playgroud)
目标对象上的onData方法由库调用为回调.在python中,我们从PyTarget继承并实现另一个方法.然后我们使用call_method <>来调用该方法.gil_lock获取锁,并通过RIAA保证获取的线程状态始终是一个版本,并且实际上它总是在超出范围时释放.
但是当我在一个试图在这个函数上获得大量回调的脚本中运行它时,它总是会出现段错误.脚本看起来像这样:
# Initialize the library and …Run Code Online (Sandbox Code Playgroud) 我想在Windows 7上使用图形工具,但我在安装它时遇到了麻烦.
此处列出的所有要求均已成功安装.安装了Python 2.7 C:\python27.使用mingw成功编译了Boost 1.49.0,安装了C:\boost并且BOOST_ROOT环境变量指向它.Boost在调试和发布模式下编译,静态和动态.
configure从MSyS内部调用会导致以下错误.
configure: error:
Could not link test program to Python. Maybe the main Python library has been
installed in some non-standard library path. If so, pass it to configure,
via the LDFLAGS environment variable.
Example: ./configure LDFLAGS="-L/usr/non-standard-path/python/lib"
============================================================================
ERROR!
You probably have to install the development version of the Python package
for your distribution. The exact name of this package varies among them.
============================================================================
Run Code Online (Sandbox Code Playgroud)
调用 …
我使用安装boost brew install --build-from-source --with-python --fresh -vd boost.然而,当我make pycaffe在Caffe项目中运行时,我得到了这个错误:ld: library not found for -lboost_python.我该如何安装该库?find / -name libboost_python* 什么都没有.
我有一个包,我想用 sphinx 记录。该包由几个本机模块(使用 boost-python 生成)和一个__init__.py
所述__init__.py确实一堆升压Python模块的(记录的)猴修补的,并提供了一堆便利功能。
我一直无法弄清楚如何告诉 sphinx 基于__init__.py. 我在搜索中发现的只是如何让 sphinx 从类__init__方法生成文档,这不是我所追求的。
C++模型
假设我有以下要向Python公开的C++数据结构.
#include <memory>
#include <vector>
struct mystruct
{
int a, b, c, d, e, f, g, h, i, j, k, l, m;
};
typedef std::vector<std::shared_ptr<mystruct>> mystruct_list;
Run Code Online (Sandbox Code Playgroud)
提升Python
我可以使用boost :: python使用以下代码相当有效地包装它们,轻松地允许我使用现有的mystruct(复制shared_ptr)而不是重新创建现有对象.
#include "mystruct.h"
#include <boost/python.hpp>
using namespace boost::python;
BOOST_PYTHON_MODULE(example)
{
class_<mystruct, std::shared_ptr<mystruct>>("MyStruct", init<>())
.def_readwrite("a", &mystruct::a);
// add the rest of the member variables
class_<mystruct_list>("MyStructList", init<>())
.def("at", &mystruct_list::at, return_value_policy<copy_const_reference>());
// add the rest of the member functions
}
Run Code Online (Sandbox Code Playgroud)
用Cython
在Cython中,我不知道如何从mystruct_list中提取项目,而不复制底层数据.我不知道如何MyStruct从现有的初始化shared_ptr<mystruct>,而不是以各种形式复制所有数据.
from libcpp.memory cimport shared_ptr
from cython.operator cimport …Run Code Online (Sandbox Code Playgroud) pybind11 是否无缝适用于 C++14 和 C++17?
我计划在我的项目中使用 Boost.python,该项目目前使用 C++11。将来我可能必须升级到 C++14 或 C++17。所以我想了解这里的正确选择是什么 - boost.python 或 pybind11。
从 pybind11 文档中,它说 - “C++11 和 Python 之间的无缝可操作性”所以有点困惑