How to return new C ++ objects in Cython?

I suspect there is a simple answer to this question, but I need help getting started with Cython. I have an existing C ++ code base that I want to open Python through Cython. For each class I want to open, I create a Cython cppclass _ClassName and a Python ClassName class ClassName .

Minmal example:

 Object.h CythonMinimal.pyx setup.py 

the contents of Object.h :

 class Object { public: Object clone() { Object o; return o; } }; 

CythonMinimal.pyx content:

 cdef extern from "Object.h": cdef cppclass _Object "Object": _Object() except + _Object clone() cdef class Object: cdef _Object *thisptr def __cinit__(self): self.thisptr = new _Object() def __dealloc__(self): del self.thisptr def clone(self): return self.thisptr.clone() 

setup.py content

 from distutils.core import setup from distutils.extension import Extension from Cython.Build import cythonize from Cython.Distutils import build_ext import os os.environ["CC"] = "g++-4.7" os.environ["CXX"] = "g++-4.7" modules = [Extension("CythonMinimal", ["CythonMinimal.pyx"], language = "c++", extra_compile_args=["-std=c++11"], extra_link_args=["-std=c++11"])] for e in modules: e.cython_directives = {"embedsignature" : True} setup(name="CythonMinimal", cmdclass={"build_ext": build_ext}, ext_modules=modules) 

This is the error I get when compiling:

 cls ~/workspace/CythonMinimal $ python3 setup.py build running build running build_ext cythoning CythonMinimal.pyx to CythonMinimal.cpp Error compiling Cython file: ------------------------------------------------------------ ... def __dealloc__(self): del self.thisptr def clone(self): return self.thisptr.clone() ^ ------------------------------------------------------------ CythonMinimal.pyx:18:27: Cannot convert '_Object' to Python object building 'CythonMinimal' extension creating build creating build/temp.macosx-10.8-x86_64-3.3 g++-4.7 -Wno-unused-result -fno-common -dynamic -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -I/usr/local/include -I/usr/local/opt/sqlite/include -I/usr/local/Cellar/python3/3.3.0/Frameworks/Python.framework/Versions/3.3/include/python3.3m -c CythonMinimal.cpp -o build/temp.macosx-10.8-x86_64-3.3/CythonMinimal.o -std=c++11 cc1plus: warning: command line option '-Wstrict-prototypes' is valid for C/ObjC but not for C++ [enabled by default] CythonMinimal.cpp:1:2: error: #error Do not use this file, it is the result of a failed Cython compilation. error: command 'g++-4.7' failed with exit status 1 

I assume that _Object.clone should return _Object (type cppclass), but Objet.clone should return Object (type Python). But how?

+7
source share
1 answer

You are returning a C ++ object in a python function that is only allowed to return python objects:

 def clone(self): return self.thisptr.clone() 

Do it like this:

 cdef _Object clone(self) except *: return self.thisptr.clone() 

But it depends on what you are trying to do, you probably want to return Object, not _Object, so I would modify it like this:

 cdef class Object: cdef _Object thisobj cdef _Object *thisptr def __cinit__(self, Object obj=None): if obj: self.thisobj = obj.thisobj.clone() self.thisptr = &self.thisobj def __dealloc__(self): pass def clone(self): return Object(self) 
+5
source

All Articles