Python — модуль Cython c ++, конструктор вызывается несколько раз

Я пытаюсь обернуть мой класс C ++ в Python, используя Cython. Я могу создать файл so и импортировать его на python, но конструктор моего класса c ++ вызывается несколько раз.

Это то, что я сделал до сих пор.

файл: RtlNodeGraphDBReader.h

#ifndef _RTLNODEGRAPHDB_READER_H_
#define _RTLNODEGRAPHDB_READER_H_

#include <iostream>

class RtlNodeGraphDBReader
{
public:
RtlNodeGraphDBReader();
~RtlNodeGraphDBReader();
};

#endif /* _RTLNODEGRAPHDB_READER_H_ */

файл: RtlNodeGraphDBReader.cxx

#include "RtlNodeGraphDBReader.h"
RtlNodeGraphDBReader::RtlNodeGraphDBReader()
{
std::cout << "Hello\n";
}RtlNodeGraphDBReader::~RtlNodeGraphDBReader()
{

}

файл: nodegraph_dbreader.pyx

# distutils: language = c++
# distutils: sources = RtlNodeGraphDBReader.cxx

cdef extern from "RtlNodeGraphDBReader.h":
cdef cppclass RtlNodeGraphDBReader:
RtlNodeGraphDBReader() except +

cdef class PyRtlNodeGraphDBReader:
cdef RtlNodeGraphDBReader c_nodegraph_dbreader      # hold a C++ instance which we're wrapping
def __cinit__(self):
self.c_nodegraph_dbreader = RtlNodeGraphDBReader()

файл: setup.py

from distutils.core import setup, Extension
from Cython.Build import cythonize
from Cython.Distutils import build_ext

modules = [Extension("nodegraph_dbreader",
sources=["nodegraph_dbreader.pyx", "../RtlNodeGraphDBReader.cxx"],
include_dirs = [".."],
libraries = ["timecap"],
library_dirs = ["/usr/local/lib64"],
language = "c++")]

setup(ext_modules = modules, cmdclass = {"build_ext" : build_ext})

После запуска setup.py build_ext --inplace Файл nodegraph_dbreader.so создан. И я могу импортировать в Python. Но, как вы можете видеть ниже: Hello печатается трижды.

>>> import nodegraph_dbreader
>>> h = nodegraph_dbreader.PyRtlNodeGraphDBReader()
Hello
Hello
Hello
>>>

0

Решение

Проблема в этой строке:

self.c_nodegraph_dbreader = RtlNodeGraphDBReader()

Если вы просто хотите создать экземпляр по умолчанию, вы уже получили его без этой строки.

Добавляя эту строку, вы явно создаете второй такой экземпляр, а затем копируете его поверх оригинала, и … я не уверен, как именно все это работает, но я предполагаю, что автоматически сгенерированный конструктор копирования вызывает конструктор по умолчанию в третий раз.

1

Другие решения

Других решений пока нет …