gpt4 book ai didi

Cython 指针继承

转载 作者:行者123 更新时间:2023-12-01 10:59:52 25 4
gpt4 key购买 nike

问题

我有一个基类 LinkPredictor 和一个派生自 C++ 中的 LinkPredictor 的子类 KatzIndex。现在我有另一个类,它的构造函数中需要一个指向 LinkPredictor 的指针。

我想将这些类包装在 Cython 中,以便在 Python 中使用它们。

我的尝试

CPP:

class LinkPredictor { ... }
class KatzIndex : public LinkPredictor { ... }
class KFoldCrossValidator {
public:
KFoldCrossValidator(LinkPredictor* lp) { ... }
}

赛通:

cdef extern from ".../LinkPredictor.h":
cdef cppclass _LinkPredictor:
_LinkPredictor(...) except +

cdef class LinkPredictor:
def __cinit__(self):
return

cdef extern from ".../KatzIndex.h":
cdef cppclass _KatzIndex(_LinkPredictor):
_KatzIndex(...) except +
...

cdef class KatzIndex(LinkPredictor):
cdef _KatzIndex* _this
...

cdef extern from ".../KFoldCrossValidator.h":
cdef cppclass _KFoldCrossValidator:
_KFoldCrossValidator(_LinkPredictor* linkPredictor) except +
...

cdef class KFoldCrossValidator:
cdef _KFoldCrossValidator* _this

def __cinit__(LinkPredictor linkPredictor):
self._this = new _KFoldCrossValidator(linkPredictor._this)
...

问题

上面的方法是行不通的。 Cython 抛出以下错误信息:

Error compiling Cython file:
------------------------------------------------------------
...
cdef _KFoldCrossValidator* _this

def __cinit__(self, LinkPredictor linkPredictor):
self._this = new _KFoldCrossValidator(linkPredictor._this)
^
------------------------------------------------------------

.../project.pyx:X:Y: Cannot convert Python object to '_LinkPredictor *'

我认为发生这种情况是因为 _this 仅在 KatzIndex 中声明,它具有类型 _KatzIndex* 而不是 _LinkPredictor*。现在我尝试从 _LinkPredictor_KatzIndex 声明继承关系(通过声明 _KatzIndex(_LinkPredictor))并希望 Cython 接受 _this 类型为 _LinkPredictor* 作为 _KatzIndex 派生自 _LinkPredictor。但事实似乎并非如此。

你对此有何看法?

最佳答案

您的问题是您的基类 (LinkPredictor) 的 python 包装器将需要包含一个指针成员,该成员然后可以被派生类覆盖。

举个例子,我们正在包装以下 C++ 库:

foo.hpp

class Base {
public:
virtual double a();
};

class Derived : public Base {
public:
virtual double a();
};

class Using {
public:
double a;
Using(Base *b);
};

foo.cpp

#include "foo.hpp"

double Base::a()
{
return 1.0;
}

double Derived::a()
{
return 2.0;
}

Using::Using(Base *b) : a(b->a())
{}

然后我们可以将包装器写成

pyfoo.pyx

cdef extern from "foo.hpp":
cdef cppclass Base:
Base() except +

cdef cppclass Derived(Base):
Derived() except +

cdef cppclass Using:
Using(Base *b) except +
double a

cdef class PyBase(object):
cdef Base *_this
def __cinit__(self):
if type(self) != PyBase:
return
self._this = new Base()

def __dealloc__(self):
if self._this is not NULL:
del self._this
self._this = NULL

cdef class PyDerived(PyBase):
def __cinit__(self):
self._this = new Derived()

def __dealloc__(self):
if self._this is not NULL:
del self._this
self._this = NULL

cdef class PyUsing(object):
cdef Using *_this
def __cinit__(self, PyBase b):
self._this = new Using(b._this)

def a(self):
return self._this.a

def __dealloc__(self):
if self._this is not NULL:
del self._this
self._this = NULL

除此之外,您可能还想通读这个 tutorial

关于Cython 指针继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29156682/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com