Wrapping custom type C++ pointer in Cython

user279545

What is the best way to wrap a custom type C++ pointer using Cython?

For example:

import numpy as np
cimport numpy as np

cdef extern from "A_c.h"
    cdef cppclass A:
       A();
       void Foo(A* vec);

cdef class pyA:
    cdef A *thisptr
    def ___cinit___(self):
        self.thisptr = new A()
    def __dealloc___(self):
        del self.thisptr

How should I use cython to wrap Foo? I have tried the following but I have gotten assertion errors from Buffer.py or the error that A is not a base type of memoryview slice

def Foo(self, np.ndarray[A, mode='c'] vec)
def Foo(self, A[::1] vec)   
michitux

Basically every time you want to pass an object of type A or a pointer to it you should use a Python object of type pyA - which is actually very similar to a pointer apart from the fact that it has reference counting, so it is like a shared_ptr in C++11, just that it only knows about references in Python (or Cython). [Edit] Note that Python objects can be None, you can easily prevent this using the not None clause.

Of course this is not only true for parameters but also for return types, so every method that returns a pointer to an object of type A should return a pyA-object instead. For doing this you can create a cdef method name for example setThis that allows to set the pointer that is contained.

As mentioned already above, memory management is done in Python if you wrap pointers this way so on the one hand you need to ensure that if your C++ objects holds a pointer to an object that the Python object is not deleted (e.g. by storing a reference to the Python object in Cython) and on the other hand you should not delete objects from C++ if they are still contained in a Python object. You could also add flags to your Cython objects if the C++ object shall be deleted or not if you already have some kind of memory management in C++.

I've extended your example a bit in order to illustrate how this can be implemented in Cython:

cdef extern from "A_c.h":
    cdef cppclass A:
        A()
        void Foo(A* vec)
        A* Bar()

    cdef cppclass AContainer:
        AContainer(A* element)

cdef class pyA:
    cdef A *thisptr
    def ___cinit___(self):
        self.thisptr = new A()

    def __dealloc___(self):
        del self.thisptr

    cdef setThis(self, A* other):
        del self.thisptr
        self.thisptr = other
        return self

    def Foo(self, pyA vec not None): # Prevent passing None
        self.thisptr.Foo(vec.thisptr)

    def Bar(self):
        return pyA().setThis(self.thisptr.Bar())

cdef class pyAContainer:
    cdef AContainer *thisptr
    cdef pyA element

    def __cinit__(self, pyA element not None):
        self.element = element # store reference in order to prevent deletion
        self.thisptr = new AContainer(element.thisptr)

    def __dealloc__(self):
        del self.thisptr # this should not delete the element
        # reference counting for the element is done automatically

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Wrapping C++ code with function pointer as template parameter in cython

Simple wrapping of C code with cython

Wrapping an imported C pointer in an Ada tagged type of the same size

Function pointer in cython extension type

"Cannot convert Python object argument to type '<typename>'" - error while wrapping c++-classes with Cython

Wrapping a C library in Python: C, Cython or ctypes?

The purpose of wrapping a pointer in struct in C

Type from a custom C++ library within Cython?

Cython Wrapping openmp c code with pragma

Cython wrapping c++ WHND casting pointers

cython wrapping of a templated c++ class gives undefined symbol

How to handle calling convention when wrapping C-code in Cython?

wrapping a C library (GSL) in a cython code by using callback

Minimal example of wrapping C code with Cython- passing int and struct

Handling pointers when wrapping C++ class with Cython

Wrapping C++ friend non-member operator in Cython

wrapping C++, How to do different classes operation in cython

Cython modifiy pointer from c++

Return c++ object (not a pointer preferably) in cython

Pass a pointer to an array value from Cython to C

Call a C function that returns a pointer from cython

Using pointer to C++ vectors in Cython

Wrapping a typedefed enum in cython

Wrapping method with default argument that is a null pointer to another wrapped type

Memory allocator with custom pointer type

Go custom type definition pointer

C#, .Net and wrapping Writeline for custom logging

cython exception ignored while having return type as void* (void pointer)

Type conversion with pointer C