Boost.Python:在Python中填写传入的缓冲区 [英] Boost.Python: Fill in a passed in buffer in Python
问题描述
我想知道是否可以在Python中填充缓冲区(具有以下条件),如果可以,怎么办?
I was wondering whether it's possible to fill in a buffer (with the following conditions) in Python and if so how?
我在C ++中有一个缓冲区,需要填写Python.缓冲区的地址是通过GetAddress
方法获得的,该方法返回 void指针到缓冲区的地址.
I have a buffer in C++ that I need to fill in Python. The Address of the buffer is obtained through the GetAddress
method which returns a void pointer to the buffer's address.
#include <boost/smart_ptr/shared_ptr.hpp>
class Foo
{
public:
Foo(const unsigned int length)
{
m_buffer = boost::shared_ptr< unsigned char >( new unsigned char[ length ] );
}
~Foo(){}
void* GetAddress( ) const
{
// cast for the sake of this question
return reinterpret_cast< void* >( m_buffer.get() );
}
private:
boost::shared_ptr< unsigned char > m_buffer;
Foo();
Foo(const Foo&);
};
使用Py ++,我可以生成Boost.Python包装器,将类导出到Python,如下所示:
Using Py++ I can generate the Boost.Python wrapper to export the class to Python as follows:
#include "boost/python.hpp"
#include "foo.hpp"
namespace bp = boost::python;
BOOST_PYTHON_MODULE(MyWrapper){
{ //::Foo
typedef bp::class_< Foo, boost::noncopyable > Foo_exposer_t;
Foo_exposer_t Foo_exposer = Foo_exposer_t( "Foo", bp::init< unsigned int >(( bp::arg("length") )) );
bp::scope Foo_scope( Foo_exposer );
bp::implicitly_convertible< unsigned int const, Foo >();
{ //::Foo::GetAddress
typedef void * ( ::Foo::*GetAddress_function_type )( ) const;
Foo_exposer.def(
"GetAddress"
, GetAddress_function_type( &::Foo::GetAddress )
, bp::return_value_policy< bp::return_opaque_pointer >() );
}
}
}
在Python中,GetAddress的输出对于内存地址为空*:
In Python, the output of the GetAddress is a void * to the memory address:
>>> import MyWrapper
>>> foo = MyWrapper.Foo(100)
>>> address = foo.GetAddress()
>>> print address
<void * object at 0x01E200B0>
>>>
问题是Python不允许我使用void *地址对象做任何事情.如果我尝试访问缓冲区中的第二个元素,则不会执行以下任何操作:
Problem is Python doesn't let me do anything with the void * address object. If I try to access the second element in buffer, none of the following work:
>>> address + 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'void *' and 'int'
>>> address[1]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'void *' object is unsubscriptable
>>>
环境:Visual Studio 2008,Boost 1.44,gcc-xml 0.9.0,py ++ 1.0.0,pygccxml 1.1.0,Python 2.6.6
Environment: Visual Studio 2008, Boost 1.44, gcc-xml 0.9.0, py++ 1.0.0, pygccxml 1.1.0, Python 2.6.6
推荐答案
Python并不真正处理指针.您可以将其中一个导出为不透明的Cookie,但永远不能执行任何操作(除非将其传递回c ++).
Python does not really deal with pointers. You can export one as a opaque cookie, but you can never do anything with it (except pass it back to c++).
在您的情况下,我会做的就是扭转它.不用返回指向python的指针,而是在c ++中提供一个从python获取缓冲区"的函数.
What I would do in your case, is to reverse it. Instead of returning to pointer to python, have a function in c++ that takes a "buffer" from python.
namespace bp = boost::python
void FillBuffer(Foo& this, bp::list buff)
{
unsigned char* addr = reinterpret_cast< unsigned char* >( this.GetAddress() );
for(int i = 0; i < bp::len(buff); i++)
addr[i] = bp::extract< unsigned char >( buff[i] );
}
Foo_exposer.def("FillBuffer", &FillBuffer);
现在,您可以在中传递列表以填充缓冲区.您可以创建类似的函数以将缓冲区填充到列表中并返回python.当然,您将要更加小心缓冲区溢出等问题,但这应该给您正确的想法.
Now you can pass a list in to fill the buffer. You can create an similar function to stuff a buffer into a list and return it python. You will, of course, want to be much more careful about buffer overruns and such, but this should give you the right idea.
这篇关于Boost.Python:在Python中填写传入的缓冲区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!