c++ - 如何在 Cython 中包装来自 C++ 的 std::shared_ptr 和 std::vector ?

标签 c++ cython shared-ptr stdvector

我正在尝试使用 Cython 将 C++ 库包装到 python API 中。我想要包装的类具有以下模板:

template<typename Value>
class ClassToWrap
{

public:
    typedef std::shared_ptr<std::vector<Value> > TypeToWrap;

    ClassToWrap(TypeToWrap data)
    {
    }
}

我对 C++ 标准库没有信心。如何将 TypeToWrap 包装在 Cython 中,使其能够以简单的方式(例如数组或多维数组)进行初始化,例如使用 for 赋值循环?感谢您的任何建议。

最佳答案

假设您有一个 C++ header ,如下所示:

// cpp_class.h

#include <memory>
#include <vector>

template<typename Value>
class ClassToWrap
{
public:
    typedef std::shared_ptr<std::vector<Value> > TypeToWrap;

    ClassToWrap(TypeToWrap data) : obj(std::move(data))
    {
    }
private:
    TypeToWrap obj;
};

您需要将此类公开给 cython,这是由 cython wrapping Cpp 中的 cdef extern 完成的文档。

# my_cy_class.pyx

# distutils: language = c++

from libcpp.memory cimport make_shared, shared_ptr
from libcpp.vector cimport vector

cdef extern from "cpp_class.h" nogil:
    cdef cppclass ClassToWrap[T]:
        ctypedef shared_ptr[vector[T]] TypeToWrap
        ClassToWrap(TypeToWrap)
        # define anything you intend to use

请注意,您只需要定义函数,而不需要它们的实现。

其次,让我们定义一个 cython 类来包装它并将其暴露给 python,因为 python 要使用它,所以它需要知道 T 的类型,我们假设它是一个 int:

from cython.operator cimport dereference as deref
from libcpp.utility cimport move

cdef class wrapper_class:
    cdef ClassToWrap[int]* wrapped_obj  # needs to be a defined type and heap allocated

    def __cinit__(self, some_list):
        cdef vector[int] v = some_list
        cdef ClassToWrap[int].TypeToWrap ptr = make_shared[vector[int]](move(v))
        self.wrapped_obj = new ClassToWrap[int](move(ptr))
        # deref(self.wrapped_obj).foo()

    def __dealloc__(self):
        del self.wrapped_obj

您可能想知道为什么使用指向对象的指针?原因是因为您的对象没有默认的零参数构造函数,并且 cython 需要一个默认的零参数构造函数才能使用 __cinit__ 和 __dealloc__ 保证对其进行堆栈分配没有内存泄漏

注意,some_list不需要是一个python列表,它可以很容易地是一个numpy数组,并且事先知道类型可以帮助编译器优化它的代码,以下代码可以测试一下。

import pyximport
script_args = ["--cython-cplus"]
setup_args = {
    "script_args": script_args,
    "include_dirs": ['.'],

}
pyximport.install(setup_args=setup_args, language_level=3,)

import numpy as np
import my_cy_class

inputs = np.array([1,2,3,4,5])
a = my_cy_class.wrapper_class(inputs)

关于c++ - 如何在 Cython 中包装来自 C++ 的 std::shared_ptr 和 std::vector ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75626349/

相关文章:

python-3.x - 使用整数的内存 View 索引 Cython 内存 View

c++ - 删除原指针后访问weak_ptr

c++ - make_shared如何为manager object和managed object分配单个动态内存

c++ - 我的 PRNG 实现与我要复制的实现有何不同?

c++ - 带有破坏操作的侵入式引用计数

c++ - 当我在 Linux 上使用 STL 编译 C++ 程序时,STL 库是如何链接的?

c++ - 如何使用静态转换管理共享对象的生命周期?

c++ - 在C++中,如何从1行中获取字符串, float 和整数的输入?

c++ - 使用 Cython 和 distutilis 方法从 Python 调用 C++ 代码

cython - 一些标准的 C 库数学运算与 noGIL 不兼容