当前位置: 首页 > 知识库问答 >
问题:

Cython:使用原始指针进行重载构造函数初始化

钮瀚
2023-03-14

我试图包装两个C++类:Cluster和ClusterTree。ClusterTree有一个方法get_current_cluster(),它实例化一个集群对象,并返回对它的引用。ClusterTree拥有集群对象,并在C++中管理其创建和删除。

我用cython包装了Cluster,生成了PyCluster。

PyCluster应该有两种创建方式:

1)通过传入两个数组,这意味着Python应该通过直接传入一个原始C++指针(由ClusterTree的get_current_cluster())创建)来自动处理删除(通过__dealloc___
2)。

from libcpp cimport bool
from libcpp.vector cimport vector

cdef extern from "../include/Cluster.h" namespace "Terran":
    cdef cppclass Cluster:
        Cluster(vector[vector[double]],vector[int]) except +

cdef class PyCluster:
    cdef Cluster* __thisptr
    __autoDelete = True

    def __cinit__(self, vector[vector[double]] data, vector[int] period):
        self.__thisptr = new Cluster(data, period)  

    @classmethod
    def __constructFromRawPointer(self, raw_ptr):
        self.__thisptr = raw_ptr
        self.__autoDelete = False

    def __dealloc__(self):
        if self.__autoDelete:
            del self.__thisptr

cdef extern from "../include/ClusterTree.h" namespace "Terran":
    cdef cppclass ClusterTree:
        ClusterTree(vector[vector[double]],vector[int]) except +
        Cluster& getCurrentCluster()

cdef class PyClusterTree:

    cdef ClusterTree *__thisptr

    def __cinit__(self, vector[vector[double]] data, vector[int] period):
        self.__thisptr = new ClusterTree(data,period)

    def __dealloc__(self):
        del self.__thisptr

    def get_current_cluster(self):

        cdef Cluster* ptr = &(self.__thisptr.getCurrentCluster())
        return PyCluster.__constructFromRawPointer(ptr)

这导致:

Error compiling Cython file:
------------------------------------------------------------
...
    def get_current_cluster(self):
        cdef Cluster* ptr = &(self.__thisptr.getCurrentCluster())
        return PyCluster.__constructFromRawPointer(ptr)
                                                     ^
------------------------------------------------------------

terran.pyx:111:54: Cannot convert 'Cluster *' to Python object

注我不能cdef__init__或@classmethods。

共有1个答案

卢伟志
2023-03-14

指针只能作为参数传递给cdef函数,而cinit必须是def函数。但是提供一个classmethod几乎是要走的路!

cdef Cluster* __thisptr
cdef bool __wrapped  ## defaults to False

@staticmethod
cdef PyCluster wrap(Cluster* ptr):
    cdef PyCluster pc = PyCluster([], [])  ## Initialize as cheaply as possible
    del pc.__thisptr  ## delete the old pointer to avoid memory leaks!
    pc.__thisptr = ptr
    pc.__wrapped = True
    return pc
 类似资料:
  • Rust通过限制智能指针的行为保障了编译时安全,不过仍需要对指针做一些额外的操作。 *const T和*mut T在Rust中被称为“裸指针”。它允许别名,允许用来写共享所有权的类型,甚至是内存安全的共享内存类型如:Rc<T>和Arc<T>,但是赋予你更多权利的同时意味着你需要担当更多的责任: 不能保证指向有效的内存,甚至不能保证是非空的 没有任何自动清除,所以需要手动管理资源 是普通旧式类型,也

  • 我有以下练习: 添加代码以使其正常运行。 我加了一个私人财产 和一个公共构造师 我添加了int-val,作为构造函数为MyVal分配一个非临时对象地址的一种方式,比如x。 有没有一个简洁(呃)的方法来回答这个练习?

  • 问题内容: 我有两个班,第一个是我的主班,第二个是我的编辑框架班。 我的第二个类(UpdateGUI)在其构造函数中提供oldName,并对其进行编辑,当我单击时,它将newName发送给我的第一个类。 我的第二堂课: 我的问题是,为什么newName为null? 更新: UpdateGUIDialog类: 输出: 我需要打印而不是null。 问题答案: Java对象有点像真实对象。并顾名思义:它

  • 考虑以下代码: 以下是一些引用的标准 拷贝初始化 从cppreference复制引用的初始化 如果object是lvalue表达式,其类型是T或从T派生的,且具有相等或较少CV限定性,则该引用绑定到由lvalue标识的对象或其基类子对象。 如果object是lvalue表达式,其类型隐式转换为T或从T派生的类型,具有相等或较少CV限定性,则考虑源类型及其基类返回lvalue引用的非显式转换函数,并

  • 问题内容: 另一个链接的问题是在使用strcpy()时出现细分错误吗? 我有一个结构: 如何初始化指向上述类型结构的指针,以及如何初始化指向结构内部的10个字符串(incall [])的指针。 我首先初始化字符串,然后初始化结构。 谢谢。 编辑:我猜我用错了字,应该说分配。实际上,我将此结构作为线程的参数传递。线程数不是固定的,作为参数发送的数据结构对于每个线程都必须是唯一的,并且是“线程安全的”

  • 主要内容:初始化 const 成员变量构造函数的一项重要功能是对成员变量进行初始化,为了达到这个目的,可以在构造函数的函数体中对成员变量一一赋值,还可以采用 初始化列表。 C++构造函数的初始化列表使得代码更加简洁,请看下面的例子: 运行结果: 小明的年龄是15,成绩是92.5 李华的年龄是16,成绩是96 如本例所示,定义构造函数时并没有在函数体中对成员变量一一赋值,其函数体为空(当然也可以有其他语句),而是在函数首部与函数体之间添