Boost.pythonその2

vector_indexing_suiteではまった。
shared_ptrを格納したvectorから取り出したオブジェクトのメソッド呼び出しがうまくいかずにはまる。

こんなの

struct VertexBuffer
{
std::vector<boost::shared_ptr<IndexBufferArray> > &getBuffers();
};

エラー

Boost.Python.ArgumentError: Python argument types in
    IndexBuffer.getName(IndexBuffer)
did not match C++ signature:
    getName(class IndexBuffer {lvalue})

http://www.mail-archive.com/cplusplus-sig@python.org/msg00904.html
この件かもしれぬ。
Fixed it.
とあるけどなー。

テストコード

#include <boost/shared_ptr.hpp>
#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <vector>

class IndexBuffer
{
  std::string name_;
public:
  IndexBuffer(const std::string &name)
    :name_(name)
    {}

  std::string getName()const{ return name_; }
};
typedef boost::shared_ptr<IndexBuffer> IndexBufferPtr;
//typedef IndexBuffer* IndexBufferPtr;
typedef std::vector<IndexBufferPtr> IndexBufferArray;

class VertexBuffer
{
  IndexBufferArray buffers_;

public:
  IndexBufferPtr add(const std::string &name)
  {
    IndexBufferPtr buffer(new IndexBuffer(name));
    buffers_.push_back(buffer);
    return buffer;
  }

  IndexBufferArray &getBuffers(){ return buffers_; }
  size_t getBufferCount(){ return buffers_.size(); }
  IndexBufferPtr getBuffer(size_t index){ return buffers_[index]; }

  static boost::shared_ptr<VertexBuffer>
    create()
    {
      return boost::shared_ptr<VertexBuffer>(new VertexBuffer);
    }
};

BOOST_PYTHON_MODULE(vertexbuffer)
{
  using namespace boost::python;

  // うまくいかない
  class_<IndexBufferArray>("IndexBufferArray")
    .def(vector_indexing_suite<IndexBufferArray>())
    ;

  class_<IndexBuffer, IndexBufferPtr /* HeldType(派生型) */ >(
      "IndexBuffer", no_init/* pythonでnewできないように */)
    .def("getName", &IndexBuffer::getName)
    ;

  class_<VertexBuffer>("VertexBuffer")
    .def("create", &VertexBuffer::create ).staticmethod("create")
    .def("add", &VertexBuffer::add, return_value_policy<return_by_value>()/*shared_ptrの値渡し*/)
    .def("getBuffers", &VertexBuffer::getBuffers, return_value_policy<copy_non_const_reference>())
    // 代替インターフェース
    .def("getBufferCount", &VertexBuffer::getBufferCount)
    .def("getBuffer", &VertexBuffer::getBuffer)
    ;
}
import vertexbuffer

dir(vertexbuffer)

v=vertexbuffer.VertexBuffer()

for i in xrange(10):
    indexBuffer=v.add("indexBuffer %d" % i)
    print indexBuffer,
    print indexBuffer.getName()

print

for indexBuffer in v.getBuffers(): # エラー
#for i in xrange(v.getBufferCount()): # 代替
#    indexBuffer=v.getBuffer(i)
    print dir(indexBuffer)
    print indexBuffer, 
    #print indexBuffer.xxx()
    print indexBuffer.getName()