Подтвердить что ты не робот

Структура проекта для переноса многих классов С++ в cython на один общий объект

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

Я изучаю cython, пытаясь немного поменять небольшие части библиотеки, которую я уже использую, которая в настоящее время завернута в boost:: python. Я внес небольшой вклад в эту оболочку boost и использую ее как ссылку на С++, в то время как в то же время я использую привязки ZeroMQ Python как ссылку на cython.

Мой вопрос о структуре проекта. Текущая версия boost этого lib компилируется в один .so, и это моя цель. Я быстро обнаружил, что вы не можете напрямую скомпилировать несколько модулей .pyx в один .so. Затем я начал сходить по пути определения файлов cppclass in pxd, а их соответствующие python экспортировал классы реализации в .pxi и пытался включить их в один pyx для компиляции. Хотя он работал сначала, как только я написал немного больше, я сталкивался с проблемами с конфликтующими множественными определениями, поскольку pxi включает в себя разные места.

Я хотел бы услышать правильный организационный подход, который касается следующих вопросов и целей:

  • Именование открытых классов так же, как cppclass (я делаю это сейчас, имея cppclass в другом имени pyd и используя импортированное пространство имен для обработки похожих имен, ala Использование cimport для разрешения конфликтов имен)
  • Одиночный .so как скомпилированный вывод (приемлемый подход?)
  • Использовать ли метод pyx multi-include в основном pyx только для этого, или если в главном pyx содержится что-то еще, кроме того, что он содержит только те, которые включены?
  • Где централизованно определять константы, которые будут экспортироваться в python?
  • Есть ли предпочтительная структура папок? Прямо сейчас у меня есть все в большой директории src под моим setup.py. Это запутывает, видя так много файлов pxi, pxd, pyx.
  • Являются ли теперь pxi ненужными? Если нет, мне нужно использовать защитник ifndef в стиле cython для обработки множественных включений между разными модулями?
  • Я знаю, что привязки python ZeroMQ создают несколько модулей и используют пакетный подход, включая их через __init__.py. Это действительно правильный подход с cython?

Для справки, проект, который я тренирую для повторного обертывания, PyOpenNI (openni). Шаблон, который этот проект ускорения принимает, состоит в том, чтобы собрать общие объекты в одном месте, а затем определить определение заголовка 1-к-1 с источником, а затем есть огромная оболочка, которая собирает все определения в одном месте. А также добавлена ​​специальная обработка исключений и утилиты.

4b9b3361

Ответ 1

Ожидая окончательного ответа, я продолжал играть с организацией своего кода. Включение файлов pyx в один pyx для компиляции уже работает.

Мой setup.py прост как:

ext_modules = [
    Extension(
        "openni", 
        ["src/openni.pyx"], 
        language="c++",
        include_dirs=['src/', '/usr/include/ni'],
        libraries=['OpenNI'],
    )
],

Основной openni.pyx выглядит следующим образом:

include "constants.pyx"
include "exceptions.pyx"
include "context.pyx"
...

У меня есть общий libopenni.pxd, чтобы предоставить остальным модулям только объявления.

Я называю мои объявления cppclass другим pxd именем, чем определения класса pyx, чтобы избежать столкновения имен:

xncontext.pxd

cdef extern from "XnCppWrapper.h" namespace "xn":
    cdef cppclass Context:
           ...

context.pyx:

from libopenni cimport *
from xncontext cimport Context as c_Context 

cdef class Context:
    cdef c_Context *handle   
        ...

Ответ 2

Ответ. Есть ли предпочтительная структура папок?

Да, предпочтительная структура папок для файлов Cython .pyx и .pxd должна обрабатывать их точно так же, как и ваши файлы .py: по одному на модуль в хорошо организованной структуре пакета. __init__.pxd файлы могут быть предоставлены так же, как файлы __init__.py, чтобы собрать кураторский набор символов для сбора кураторского набора символов из его подмодулей/пакетов для cimporting.

Правда, это создает один файл .so для каждого модуля, но эти файлы скрыты в каталоге сборки. То же самое относится к модулям построения Python; есть соответствующие файлы .so для каждого из них. Это проблема?