Функция Wrap C++, которая возвращает коммуникатор MPI с использованием Cython

Я пытаюсь обернуть функцию С++, которая не принимает никаких входных данных и возвращает коммуникатор MPI.

Фу.ч

class Foo{
 public:
  Foo(MPI_Comm _comm){
   _comm = comm;
  }
  MPI_Comm getMPIComm(){
   return comm
  }
  virtual void Foo1() = 0 

Я пробовал следующее:

источник.pyx

cimport mpi4py.MPI as MPI
from mpi4py.libmpi cimport *

cdef extern from  Foo.h:
   cdef cppclass Foo:
      Foo(MPI_Comm _comm)
      MPI_Comm getMPIComm()
      void Foo1() 

cdef class pyFoo:
   cdef Foo *thisptr
   def __cinit__(self,MPI.Comm _comm):
      pass
   def get MPIComm(self):
      c_comm = self.thisptr.getMPIComm()
      return <MPI.Comm> c_comm
   def Foo1(self):
      pass       

Этот код скомпилирован, и я смог написать код Python, который наследует этот класс. Однако, когда я попытался получить доступ к getMPIComm на уровне Python, я столкнулся с ошибкой сегментации, и ошибка, выдаваемая valgrind:

Access not within mapped region at address 0x8

Означает ли это, что я неправильно обернул getMPIComm()? Кто-нибудь знает, как я должен подойти к этому?


person user279545    schedule 11.03.2015    source источник


Ответы (1)


Я думаю, что вы никогда не выделяете *thisptr и, таким образом, получаете нарушение прав доступа при попытке вызвать на нем getMPIComm. Попробуйте создать экземпляр Foo следующим образом:

cdef class pyFoo:
   cdef Foo *thisptr
   def __cinit__(self,MPI.Comm _comm):
      self.thisptr = new Foo(_comm)
   # ...
person user0815    schedule 11.03.2015
comment
Я не уверен, как выделить *thisptr в этом случае из-за чистой виртуальной функции Foo1, и это вызывает ошибку компиляции, когда я пытался выполнить выделение указателя. Это должно происходить? - person user279545; 11.03.2015
comment
@ user279545: Да, верно. Вы не можете создать экземпляр абстрактного класса. Но тогда вы вообще не сможете использовать this-указатель. Возможно, вам следует обернуть подкласс Foo, который можно создать. Другой способ — изменить подпись Foo1 на virtual void Foo1() = {}. Это зависит от ваших потребностей. - person user0815; 11.03.2015
comment
Если бы я хотел обернуть подкласс [Foo] в этом случае, как бы я это сделал? Я все еще новичок в cython и пытаюсь разобраться. - person user279545; 11.03.2015
comment
Даже в C++ невозможно получить экземпляр Foo, потому что он абстрактен. Это означает, что должны быть другие классы, которые наследуются от Foo. И вместо того, чтобы обертывать сам Foo, вы можете просто обернуть подклассы, как вы пытались выше. В этом случае это сработает, потому что вы можете создать экземпляр thisptr. - person user0815; 11.03.2015