Я использую Cython, чтобы обернуть код C ++ и сделать его доступным в Python.Проблема, с которой я сталкиваюсь, заключается в том, что я хочу использовать обернутый класс в качестве аргумента в функции, которую я также хочу обернуть.Поэтому с точки зрения Python я хочу создать и изменить объект обернутого класса и использовать его в качестве аргумента для обернутой функции, которую я также хочу вызвать из Python.Надеемся, что приведенный ниже код продемонстрирует это.
Ниже вы можете найти минимальный пример в C ++, который я хочу обернуть:
. / CppCode / Settings / Settings.h
class Settings
{
public:
Settings();
void doSomething();
};
. / CppCode / Helper / Helper.h
#include "../Settings/Settings.h"
void myFunction(Settings settings);
Функциональность не очень важна.Поэтому я пропустил файлы .cpp.Ниже приведен мой подход к Cython:
. / CythonCode / Settings / Settings.pxd
cdef extern from "../../cppCode/Settings/Settings.h":
cdef cppclass Settings:
Settings() except +
void doSomething()
. / CythonCode / Settings / Settings.pyx
# distutils: sources = ../../cppCode/Settings/Settings.cpp
# distutils: language = c++
from Settings cimport Settings
cdef class PySettings:
cdef Settings c_settings
def __cinit__(self):
self.c_settings = Settings()
def doSomething(self):
self.c_settings.doSomething()
. / cythonCode / Helper.pxd
from Settings.Settings cimport Settings
cdef extern from "../../cppCode/Helper/Helper.h":
void myFunction(Settings settings)
. / cythonCode / Helper.pyx
# distutils: sources = ../../cppCode/Helper/Helper.cpp
# distutils: language = c++
from Helper cimport myFunction
cdef PyMyFunction(PySettings settings):
myFunction(settings)
run.py
import cythonCode.Settings.Settings as Settings
#import cythonCode.Helper as Helper
mySettings = Settings.PySettings()
mySettings.doSomething()
#Helper.myFunction(mySettings) # not working
Я надеюсь, что структурапроект понятен.Я бы на самом деле хотел бы иметь «Helper.pyx» и «Helper.pxd» в папке «Helper», но тогда я не знаю, как импортировать настройки.Если вы можете помочь мне исправить это, это также будет высоко оценено.Тем не менее, основная проблема заключается в том, чтобы заставить Helper работать так, чтобы я мог использовать его в «run.py».Файл «setup.py» для сборки модулей Cython выглядит просто так:
from distutils.core import setup
from Cython.Build import cythonize
from setuptools.extension import Extension
extensions = [
Extension("Helper", ["Helper.pyx"])
]
setup(ext_modules=cythonize(extensions))
Я делаю то же самое отдельно в папке «Настройки».
Буду очень признателен за помощь в решенииэта проблема!
РЕДАКТИРОВАТЬ : Как уже упоминалось в комментариях, есть две ошибки:
1) Это должен быть Helper.PyMyFunction (mySettings) в run.py.
2) Это должно быть def вместо cdef перед PyMyFunction, потому что я определенно хочу вызвать эту функцию из Python.
EDIT2 : я играл с вашими входамии нашел неумелое решение, которое приводит к другому вопросу.Ниже приведен код, который работает для меня:
Settings.pxd
cdef extern from "../../cppCode/Settings/Settings.h":
cdef cppclass Settings:
Settings() except +
void doSomething()
cdef extern from "../../cppCode/Helper/Helper.h":
void myFunction(Settings settings)
Settings.pyx
# distutils: sources = [../../cppCode/Settings/Settings.cpp, ../../cppCode/Helper/Helper.cpp]
# distutils: language = c++
from Settings cimport Settings, myFunction
cdef class PySettings:
cdef Settings c_settings
def __cinit__(self):
self.c_settings = Settings()
def doSomething(self):
self.c_settings.doSomething()
def PyMyFunction(PySettings settings):
myFunction(settings.c_settings)
Когда я цитирую Settings.pyx, я могу запуститьследующий код Python, и все работает нормально:
import Settings
mySettings = Settings.PySettings()
mySettings.doSomething()
Settings.PyMyFunction(mySettings)
Что мне не нравится в этом, так это то, что обе части (Настройки и myFunction) включены в один файл.Я понятия не имею, как заставить это работать, когда эти две части находятся в отдельных файлах.
EDIT3 : Чтобы решить проблему "две части в отдельных файлах", представьте следующий код:
Settings.pxd
cdef extern from "../../cppCode/Settings/Settings.h":
cdef cppclass Settings:
Settings() except +
void doSomething()
Settings.pyx
# distutils: sources = ../../cppCode/Settings/Settings.cpp
# distutils: language = c++
from Settings cimport Settings
cdef class PySettings:
cdef Settings c_settings
def __cinit__(self):
self.c_settings = Settings()
def doSomething(self):
self.c_settings.doSomething()
Helper.pxd
from Settings cimport Settings
cdef extern from "../../cppCode/Helper/Helper.h":
void myFunction(Settings settings)
Helper.pyx
# distutils: sources = ../../cppCode/Helper/Helper.cpp
# distutils: language = c++
from Helper cimport myFunction
def PyMyFunction(PySettings settings):
myFunction(settings.c_settings)
Это тот же код, что и в EDIT2, но разделенный на два файла.В Helper.pxd есть только одна дополнительная строка, которая находится «из настроек cimport Settings».Тем не менее, в Helper.pyx я получаю эту ошибку:
def PyMyFunction(PySettings settings):
^
---------------------------------------
Helper.pyx:6:17: 'PySettings' is not a type identifier
Я пытался "из настроек Cimport PySettings", но это не работает.Продолжает происходить одна и та же ошибка.Все файлы находятся в одном каталоге.