Pythonで(次の条件で)バッファに入力できるかどうか疑問に思っていました。その場合、どのように入力しますか?
Pythonに入力する必要のあるC++のバッファーがあります。バッファのアドレスは、バッファのアドレスへのvoidポインタGetAddress
を返すメソッドを介して取得されます。
#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にエクスポートできます。
#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の出力はメモリアドレスに対してvoid*です。
>>> import MyWrapper
>>> foo = MyWrapper.Foo(100)
>>> address = foo.GetAddress()
>>> print address
<void * object at 0x01E200B0>
>>>
問題は、Pythonがvoid*アドレスオブジェクトで何もできないことです。バッファ内の2番目の要素にアクセスしようとすると、次のいずれも機能しません。
>>> 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