将 python 对象传递到用 Cython 包装的类时出现 Seg 错误

Seg fault when passing python object into class wrapped with Cython

本文关键字:错误 Seg 包装 Cython 对象 python      更新时间:2023-10-16

我用Cython包装了许多C++类,他们设法编译了。但是,当我尝试使用 python 级别的模块时,我遇到了分段错误 (11),所以我想知道我包装的内容是否正确。"Foo.h"中的A是一个抽象类。

来源.pyx

cdef extern from "Foo.h":
   cdef cppclass A:
      A(MPI_comm comm, int x)
cdef extern from "Foo1.h":
   cdef cppclass B:
      B(A* obj, int y)
cdef class pyA:
   cdef A *thisptrA
   def __cinit__(self,MPI.Comm _comm, int x):
      pass
   def __dealloc__(self):
      pass
cdef class pyB:
   cdef B* thisptrB
   cdef pyA obj
   def __cinit__(self, pyA obj, int y):
      self.thisptrB = new B(obj.thisptrA, y) 
   def __dealloc__(self):
      del self.thisptrB

testscript.py

import pyA, pyB
class C(pyA):
   def __init__(self, comm, x):
      self.x = x
comm = MPI.COMM_WORLD
x = 2
y = 24
Aobj = C(comm, x)
Bobj = pyB(Aobj, y)

似乎每当我尝试初始化pyB时,语句都会发生分段错误

self.thisptrB = newB(obj.thisptrA, y)

有人知道我哪里出错了吗?

你不希望在pyA中分配thisptrA。因此,它指向的东西要么是空的,要么是随机的(我不确定哪个是 Cython)。

导致分段错误的确切原因可能隐藏在构造函数中 B ,您不会让我们做空。

您可能

还需要考虑的另一件事:您可能希望确保A的生存期超过(我假设)持有指向它的指针的B的生存期。一种方法是在PyB中保留对PyA的引用(即在__init__内,以便PyB放置self._held_A = obj