Python函数作为C++中的参数
Python function as Argument in C++
我正试图使用Boost.python.在python中公开本征3
我找不到公开函数unaryExpr (const CustomUnaryOp &func=CustomUnaryOp())
的方法
我想要的是允许我做这样的事情:
python
import libMatrix as mat
a = mat.Matrix(10, 10)
mat.unary_expr( lambda x : 1)
你知道吗??看起来可能是这样的:
void unary_expr(Matrix const& self, PyObject* callable_object)
{
cpp_callable = ??(callable_object)
self.unaryEpxr(cpp_callable);
}
===我尝试了什么:====================================
1) 我尝试使用一个简单的回调定义
typedef double(*UnaryExprType)(double);
void unary_expr(Matrix const& self, UnaryExprType a);
{
self.unaryEpxr( a );
}
但是boost不会将python函数转换为UnaryExprType。
2) 我试图实现一个结构PythonCallBack
,但它不起作用,我得到了一个错误,python签名与c++签名不匹配。
struct PythonCallBackBase
{
public:
virtual ~PythonCallBackBase() {}
virtual double operator() (double const & x) { return 0; }
};
struct PythonCallBack : PythonCallBackBase, boost::python::wrapper<PythonCallBackBase>
{
public:
typedef boost::python::wrapper<PythonCallBackBase> wrap;
double default_op(double const & x)
{
return 0;
}
double operator() (double const & x)
{
if (boost::python::override f = wrap::get_override("__call__"))
return f(x);
return PythonCallBackBase::operator ()(x);
}
};
void unary_expr(Matrix const& self, PythonCallBack a)
{
self.unaryEpxr( a );
}
错误消息
ArgumentError: Python argument types in
Matrix.unary_expr(Matrix, Boost.Python.class)
did not match C++ signature:
unary_expr(Eigen::Matrix<double, -1, -1, 0, -1, -1>, PythonCallBack)
unary_expr(Eigen::Matrix<double, -1, -1, 0, -1, -1>, double (*)(double))
Boost.Python旨在最大限度地减少与PyObject
交互的需要,并且通常可以像使用Python中的对象一样简单地使用boost::python::object
。例如,如果func
是指lambda x: 1
的boost::python::object
,那么下面是带有注释Python注释的Boost.Python用法:
// >>> func = lambda x: 1
boost::python::object func = ...;
// >>> result = func(42)
boost::python::object result = func(42);
// >>> assert(1 == result)
assert(1 == boost::python::extract<int>(result));
在这种情况下,由于C++代码可能希望函子的返回值是C++类型,而不是泛型boost::python::object
,因此可以使用包装器类型来调整函子。
/// @brief Auxiliary type that adapts a Boost.Python object to a
/// unary functor with an explicit return type.
template <typename Arg, typename Result>
class py_unary_functor
{
public:
typedef Arg argument_type;
typedef Result result_type;
py_unary_functor(boost::python::object object)
: object_(object)
{}
result_type operator()(argument_type a1)
{
return boost::python::extract<result_type>(object_(a1))();
}
private:
boost::python::object object_;
};
以下是一个完整的最小示例:
#include <boost/python.hpp>
/// @brief Mockup matrix class.
struct matrix
{
template <typename CustomUnaryOp>
void unaryExpr(CustomUnaryOp func)
{
value = func(value);
}
double value;
};
/// @brief Auxiliary type that adapts a Boost.Python object to a
/// unary functor with an explicit return type.
template <typename Arg, typename Result>
class py_unary_functor
{
public:
typedef Arg argument_type;
typedef Result result_type;
py_unary_functor(boost::python::object object)
: object_(object)
{}
result_type operator()(argument_type a1)
{
return boost::python::extract<result_type>(object_(a1))();
}
private:
boost::python::object object_;
};
/// @brief Auxiliary function used to adapt matrix::unaryExpr.
void matrix_unaryExpr(
matrix& self,
boost::python::object object)
{
py_unary_functor<double, double> func(object);
return self.unaryExpr(func);
}
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
python::class_<matrix>("Matrix")
// Expose auxiliary function.
.def("unaryExpr", &matrix_unaryExpr)
.add_property("value", &matrix::value, &matrix::value)
;
}
交互式使用:
>>> import example
>>> matrix = example.Matrix()
>>> matrix.value = 21
>>> assert(21 == matrix.value)
>>> matrix.unaryExpr(lambda x: x*2)
>>> assert(42 == matrix.value)
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 如何使用Luacneneneba API正确读取字符串和表参数
- 在派生函数中指定void*参数
- 视图中的参数推导失败:take_while
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- 使用指向成员的指针将成员函数作为参数传递
- 没有名称的C++模板参数
- 如何将enable-if与模板参数和参数包一起使用