2

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

4

1 に答える 1

2

Python は実際にはポインタを扱いません。1 つを不透明な Cookie としてエクスポートできますが、それを使用して何もすることはできませ(C++ に戻すことを除く)。

あなたの場合、私がすることは、それを逆にすることです。Python へのポインタに戻る代わりに、Python から「バッファ」を取得する関数を C++ に用意します。

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 で返すことができます。もちろん、バッファ オーバーランなどにはもっと注意を払う必要がありますが、これで正しい考えが得られるはずです。

于 2012-05-01T21:59:42.383 に答える