如何编写函数和成员函数的包装器,以便在包装函数之前和之后执行一些代码?
我正在尝试编写一些包装类或函数,使我可以在包装函数之前和之后执行一些代码。
float foo(int x, float y)
{
return x * y;
}
BOOST_PYTHON_MODULE(test)
{
boost::python::def("foo", <somehow wrap "&foo">);
}
理想情况下,包装器应该是通用的,适用于具有任何签名的函数和成员函数。
更多信息:
我正在寻找一种简单的方法来释放/重新获取围绕我昂贵的 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);
}
这种包装器将为所有类型的函数重复多次,并且我想找到一个解决方案,让我避免对所有这些进行编码。
我已经尝试了一些方法,但我能想到的最好的方法是要求用户显式地声明返回值和参数的类型,例如:
boost::python::def("foo", &wrap_gil<float, int, float>(&foo_wrapper));
但在我看来,应该可以仅将指针传递给函数(&foo_wrapper )并让编译器找出类型。
有谁知道我可以使用的技术或为我指明正确的方向?
干杯!
I'm trying to write some wrapper class or function that allows me to execute some code before and after the wrapped function.
float foo(int x, float y)
{
return x * y;
}
BOOST_PYTHON_MODULE(test)
{
boost::python::def("foo", <somehow wrap "&foo">);
}
Ideally, the wrapper should be generic, working for functions and member functions alike, with any signature.
More info:
I'm looking for a simple way to release/re-acquire the GIL around my expensive C++ calls without having to manually write thin wrappers like this:
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);
}
This kind of wrapper will be repeated several times for all kinds of functions, and I would like to find a solution that would allow me to avoid coding all of them.
I have tried some approaches, but the best I could come with required the user to explicitly state the types of return values and parameters, like:
boost::python::def("foo", &wrap_gil<float, int, float>(&foo_wrapper));
But it seems to me it should be possible to just pass the pointer to the function (&foo_wrapper) and let the compiler figure out the types.
Does anyone know a technique I could use or point me in the right direction?
Cheers!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在这种情况下,您可以编写一个封装函数的 Functor 类,然后重载 boost::python::detail::get_signature 来接受您的 Functor!
更新:还添加了对成员函数的支持!
示例:
在 python 上:
In this case, you can write a Functor class that wraps over your function, and then overload boost::python::detail::get_signature to accept your Functor!
UPDATE: Added support for member functions too!
Example:
And on python:
您是否看过 Stroustrup 在他的“包装 C++ 成员函数调用”中描述的函数包装技术”纸?还有一个SO响应这里 演示了如何以简洁的方式实现它。基本上,您会实现一个重载
operator->()
的模板。在该运算符的实现中,您将在实际函数调用之前构造一个临时对象。临时对象的构造函数和析构函数负责分别在实际函数调用之前和之后调用“pre-”和“post-”代码。Have you looked at the function wrapping technique described by Stroustrup in his "Wrapping C++ Member Function Calls" paper? There's also a SO response here that demonstrates how to implement it in a concise manner. Basically you'd implement a template that overloads
operator->()
. Within thatoperator
's implementation you'd construct a temporary object before your actual function call. The temporary object's constructor and destructor take care of invoking your "pre-" and "post-" code before and after your actual function call, respectively.