Я пытаюсь обернуть мой класс 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
>>>
Проблема в этой строке:
self.c_nodegraph_dbreader = RtlNodeGraphDBReader()
Если вы просто хотите создать экземпляр по умолчанию, вы уже получили его без этой строки.
Добавляя эту строку, вы явно создаете второй такой экземпляр, а затем копируете его поверх оригинала, и … я не уверен, как именно все это работает, но я предполагаю, что автоматически сгенерированный конструктор копирования вызывает конструктор по умолчанию в третий раз.
Других решений пока нет …