Simple Cython question regarding passing vectors to a constructor

764 views
Skip to first unread message

Jason

unread,
Feb 2, 2011, 1:30:54 PM2/2/11
to cython-users
Hi everyone,

I've got a C++ library that I'm trying to wrap using Cython. I've got
a basic question that I'm sure has been answered many times before,
but I can't seem to find a solution. Anyway, this is hopefully all of
the relevant code from my .pyx file:

from libcpp.vector cimport vector
...
ctypedef unsigned char WordLength
ctypedef unsigned long long int HashIntoType
...
cdef extern from "../lib/hashbits.hh" namespace "khmer":
cdef cppclass Hashbits:
Hashbits(WordLength, vector[HashIntoType])
...
cdef class new_hashbits:
cdef Hashbits *thisptr
def __cinit__(self, WordLength k, vector[HashIntoType] vec):
self.thisptr = new Hashbits(k, vec)

When I try to compile, I get the following:

/home/u/jason/khmer/python2/_khmermodule.pyx:270:37: Cannot convert
Python object argument to type 'vector<HashIntoType>'

What do I need to do in order to get this working? Any help that you
can provide would be greatly appreciated.

Sincerely,
Jason Pell

Robert Bradshaw

unread,
Feb 2, 2011, 2:25:14 PM2/2/11
to cython...@googlegroups.com

The signature of __cinit__ is fixed by that of __init__, i.e. it takes
a variable number of Python objects as arguments. In particular, how
else would it be invokable from Python? What could do here is have the
__cinit__ function callable, creating the empty list (or converting a
Python list into your vector), and then you would have a cdef function
that could take the C++ arguments callable only from other Cython
code. (This could be wrapped in a create_new_hashbits() cdef function
if that's the normal usecase.)

- Robert

Jason

unread,
Feb 2, 2011, 5:09:39 PM2/2/11
to cython-users
Thanks for your help, Robert. For the sake of completeness, here is
how I modified my code to get it working. I wasn't considering how the
class would actually be used in Python.

cdef class new_hashbits:
cdef Hashbits *thisptr
def __cinit__(self, WordLength k, list primes):
cdef vector[HashIntoType] v = vector[HashIntoType]()
for i in range(len(primes)):
v.push_back(primes[i])

self.thisptr = new Hashbits(k, v)


Jason

On Feb 2, 2:25 pm, Robert Bradshaw <rober...@math.washington.edu>
wrote:

Robert Bradshaw

unread,
Feb 2, 2011, 5:13:52 PM2/2/11
to cython...@googlegroups.com
On Wed, Feb 2, 2011 at 2:09 PM, Jason <jason...@gmail.com> wrote:
> Thanks for your help, Robert. For the sake of completeness, here is
> how I modified my code to get it working. I wasn't considering how the
> class would actually be used in Python.
>
> cdef class new_hashbits:
>   cdef Hashbits *thisptr
>   def __cinit__(self, WordLength k, list primes):
>      cdef vector[HashIntoType] v = vector[HashIntoType]()
>      for i in range(len(primes)):
>         v.push_back(primes[i])
>
>      self.thisptr = new Hashbits(k, v)

That would work well. For even more flexibility, you could even do

def __cinit__(self, WordLength k, primes):


cdef vector[HashIntoType] v = vector[HashIntoType]()

for a in primes:
v.push_back(a)


- Robert

Reply all
Reply to author
Forward
0 new messages