2012-05-01 4 views
2

私はPythonで(次の条件で)バッファを埋めることが可能かどうか疑問に思っていました。Boost.Python:Pythonで渡されたバッファを書き込んでください

私はC++でPythonで必要なバッファを用意しています。バッファのアドレスはGetAddressメソッドによって取得され、voidポインタをバッファのアドレスに返します。 Pyを使用して

#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&); 
}; 

++、私は次のようにPythonのにクラスをエクスポートする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>()); 

     } 
    } 
} 

を、のgetAddressの出力は、メモリアドレスへのvoid *です:

>>> import MyWrapper 
>>> foo = MyWrapper.Foo(100) 
>>> address = foo.GetAddress() 
>>> print address 
<void * object at 0x01E200B0> 
>>> 

問題点Pythonでは、void *アドレスオブジェクトでは何もできません。私は、バッファ内の第二の要素にアクセスしようとすると、次の作業のいずれ:

>>> 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年には、1.44、GCC-XML 0.9.0、PY ++ 1.0.0、1.1.0 pygccxmlブーストませんPython 2.6.6

+0

あなたの*質問*は何ですか?期待どおりに動作しないのは何ですか?どのように行うかを正確に把握できないのですか? –

+0

問題はバッファのアドレスを無効ポインタとして取得できますが、何もできません。たとえば、反復と値の割り当てをサポートしていません。すべての点ですべて良い点!私は質問を編集します。 – Ehsan

+0

バッファを満たすためのインターフェースの種類は何ですか?のインデックス?ストリームとして扱いますか? 'buffer'、' StringIO'などの既存のクラスを見ましたか?一度バッファがいっぱいになると、あなたは何をするつもりですか? –

答えて

2

実際には、Pythonはポインタを処理しません。 1つを不透明なクッキーとしてエクスポートすることはできますが、決してを実行することはできません。を実行することはできません。

私があなたの場合に行うことは、それを逆にすることです。 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を返すことができます。もちろん、バッファオーバーランなどについてもっと注意したいと思うでしょうが、これはあなたに正しいアイデアを与えるはずです。

+1

ありがとう!私はそれを試して、それは動作します。 Python側でこれを行うことができればうれしかったでしょう。 – Ehsan

+0

私のコードを修正していただきありがとうございます。私はメインボックスから離れていて、それを編集しなかった。 –

関連する問題