ascobol
ascobol

Reputation: 7716

How to use C++ operator[] in Cython?

I need to wrap a C++ class FooContainer defining the operator[]:

//foo.h:
#include <vector>
using namespace std;

struct Foo
{
  Foo()
    : value(42) {};
  int value;   
};


class FooContainer
{
public:
    FooContainer() { this->values = vector<Foo> (100) ;}
    Foo operator[](int i) {return values[i];}; // <-- the function I need to call

private:
  vector<Foo> values;    

};

I'm trying to write the corresponding .pyx file but whatever I try I can't figure out how to use Foo::operator

from cython.operator cimport dereference as deref


cdef extern from "foo.h":
   cdef cppclass CppFoo "Foo":
     pass

cdef extern from "foo.h":
   cdef cppclass CppFooContainer "FooContainer":
     FooContainer()
     Foo operator[](int)


cdef class Foo:
    cdef CppFoo * thisptr

cdef class FooContainer:
    cdef CppFooContainer* thisptr

    def __cinit__(self):
       self.thisptr = new CppFooContainer ()

    def __dealloc__(self):
       if self.thisptr:
           del self.thisptr
           self.thisptr = <CppFooContainer*> 0

    def __getitem__(self, int i):
       cdef CppFoo f  = deref(self.thisptr)[i]  #just one out of many try

I'm probably missing the trivial solution but I always end up with the error: "Cannot convert Python object to 'CppFoo'". Which is the proper way to use the operator[] ?

Upvotes: 3

Views: 1365

Answers (1)

Stephen Lin
Stephen Lin

Reputation: 5540

The usage of operator[] is correct (Cython does not require special syntax for the array indexing operator), but

cdef extern from "foo.h":
   cdef cppclass CppFooContainer "FooContainer":
     FooContainer()
     Foo operator[](int)

should be:

cdef extern from "foo.h":
   cdef cppclass CppFooContainer "FooContainer":
     CppFooContainer()
     CppFoo operator[](int)

since FooContainer and Foo refer to the Python extension class types declared afterwards rather than the C++ class types from "foo.h".

Upvotes: 3

Related Questions