Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add bool returning function #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions _test.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ def test_the_wrapped_class():
T = PyTestClass()
T.x = 15
print(T.x)
print("Is -10 positive?")
print(T.IsPositive(-10))
T = None


Expand Down
47 changes: 23 additions & 24 deletions pytestclass.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@

from testclass cimport TestClass


cdef class PyTestClass:

"""
"""
Cython wrapper class for C++ class TestClass
"""

Expand All @@ -17,23 +16,23 @@ cdef class PyTestClass:

def __cinit__(PyTestClass self):
# Initialize the "this pointer" to NULL so __dealloc__
# knows if there is something to deallocate. Do not
# knows if there is something to deallocate. Do not
# call new TestClass() here.
self._thisptr = NULL

def __init__(PyTestClass self):
# Constructing the C++ object might raise std::bad_alloc
# which is automatically converted to a Python MemoryError
# by Cython. We therefore need to call "new TestClass()" in
# __init__ instead of __cinit__.
self._thisptr = new TestClass()
self._thisptr = new TestClass()

def __dealloc__(PyTestClass self):
# Only call del if the C++ object is alive,
# Only call del if the C++ object is alive,
# or we will get a segfault.
if self._thisptr != NULL:
del self._thisptr

cdef int _check_alive(PyTestClass self) except -1:
# Beacuse of the context manager protocol, the C++ object
# might die before PyTestClass self is reclaimed.
Expand All @@ -42,54 +41,54 @@ cdef class PyTestClass:
if self._thisptr == NULL:
raise RuntimeError("Wrapped C++ object is deleted")
else:
return 0
return 0

property x:

# Here we use a property to expose the public member
# x of TestClass to Python

def __get__(PyTestClass self):
self._check_alive()
return self._thisptr.x

def __set__(PyTestClass self, value):
self._check_alive()
self._thisptr.x = <int> value

property y:

# Here we use a property to expose the public member
# y of TestClass to Python

def __get__(PyTestClass self):
self._check_alive()
return self._thisptr.y

def __set__(PyTestClass self, value):
self._check_alive()
self._thisptr.y = <int> value


def Multiply(PyTestClass self, int a, int b):
self._check_alive()
return self._thisptr.Multiply(a,b)



def IsPositive(PyTestClass self, int a):
self._check_alive()
return self._thisptr.IsPositive(a)

# The context manager protocol allows us to precisely
# control the liftetime of the wrapped C++ object. del
# is called deterministically and independently of
# is called deterministically and independently of
# the Python garbage collection.

def __enter__(PyTestClass self):
self._check_alive()
return self

def __exit__(PyTestClass self, exc_tp, exc_val, exc_tb):
if self._thisptr != NULL:
del self._thisptr
del self._thisptr
self._thisptr = NULL # inform __dealloc__
return False # propagate exceptions



11 changes: 6 additions & 5 deletions testclass.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@

class TestClass {
public:

int x, y;

TestClass();

virtual ~TestClass();

inline int Multiply(int a, int b){
return a*b;
}

inline bool IsPositive(int a){ return a>0;}
};

#endif

7 changes: 2 additions & 5 deletions testclass.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@
# Using a .pxd file gives us a separate namespace for
# the C++ declarations. Using a .pxd file also allows
# us to reuse the declaration in multiple .pyx modules.
from libcpp cimport bool as bool_t

cdef extern from "testclass.h":

cppclass TestClass:
int x,y
TestClass() except + # NB! std::bad_alloc will be converted to MemoryError
int Multiply(int a, int b)





bool_t IsPositive(int a)