c++ - 如何在 Cython 中返回新的 C++ 对象?

标签 c++ python cython

我怀疑对此有一个简单的答案,但我需要一些帮助才能开始使用 Cython。我有一个现有的 C++ 代码库,我想通过 Cython 将其公开给 Python。对于我想要公开的每个类,我创建了一个 Cython cppclass _ClassName 和 Python 包装器类 ClassName

一个最小的例子:

Object.h
CythonMinimal.pyx
setup.py

Object.h的内容:

class Object {

public:

    Object clone() {
        Object o;
        return o; 
    }

};

CythonMinimal.pyx 的内容:

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的内容

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)

这是我在编译时遇到的错误:

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

我假设 _Object.clone 需要返回一个 _Object (cppclass 类型),但是 Objet.clone 应该返回一个 对象(Python 类型)。但是如何呢?

最佳答案

你在一个只允许返回 python 对象的 python 函数中返回一个 C++ 对象:

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

让它变成这样:

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

但这取决于你想做什么,你可能想返回对象而不是_Object,所以我会这样修改它:

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)

关于c++ - 如何在 Cython 中返回新的 C++ 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16882625/

相关文章:

c++ - 将指针作为私有(private)数据成员传递给 Main 中的成员函数

c++ - 在 Win32 程序中使用 XAML 托管 API 导航到页面会导致访问冲突

python - 多次调用计算方法?

arrays - Cython - 定义二维数组

cython:你如何创建一个 cdef 类的数组

c++ - 立即调用 OnMove() 而不是等待窗口的实际移动

c++ - 使用 Boost 的多元正态分布样本

python - 线程安全 Cython RNG nogil 并行化

python - 使用 while 循环的装饰器

python - LinAlgError : Last 2 dimensions of the array must be square