Ответ 1
Как вы говорите, Cython на самом деле не поддерживает это.
Я думаю, что самый простой подход - просто вручную создать кучу файлов Cython, используя замену строк. Начните с файла "foowrapper.pxi.src" (имя по вашему желанию...):
cdef class PyFoo_{T}:
cdef Foo[{T}] *thisptr
def __cinit__(self, param):
self.thisptr = new Foo[{T}](param)
# etc
Затем запустите его через простую программу (возможно, также Python), чтобы загрузить файл, выполнить подстановку строк и снова сохранить файл под новым именем. Ключевая строка:
output = code.format(T=T) # where T is a string with a C++ class name
# e.g. "int" or "std::vector<double>"
(Очевидно, немного кода, связанного с загрузкой и сохранением, который я пропустил из лени)
Затем в вашем файле Cython вы просто "включаете" сгенерированные файлы для каждого класса. Команда "include" в Cython - это буквальный текстовый include (например, препроцессор C) и ожидает файл .pxi:
cdef extern from "header.h":
cdef cppclass Foo[T]:
Foo(T param)
# ...
include "foowrapper_int.pxi"
include "foowrapper_vectordouble.pxi
# etc
Вы должны выбрать классы для генерации во время компиляции, но это неизбежно (шаблоны являются функцией времени компиляции), поэтому вы никогда не сможете генерировать их динамически из среды сценариев Python, поскольку соответствующие Класс С++ не будет сгенерирован.
Другие параметры
Несколько других вариантов заслуживают краткого рассмотрения. Во-первых, вы можете наследовать Foo<T>
из базового класса (скажем FooBase
), который не зависит от параметра шаблона. Затем вы завернете FooBase
в Cython (создаете конструктор-подобные функции для случаев, о которых вы заботитесь). Это действительно реально, если функции, которые вы хотите вызвать, не имеют аргументов, которые зависят от типа шаблона. Очевидно, что это также связано с изменением кода на С++.
Опция раздела - это посмотреть на другой способ обертывания. Boost Python, безусловно, поддержит это изначально (но имеет свои недостатки). Я думаю, SIP/SWIG также справится (но я не знаю). Вы можете довольно легко смешивать и сопоставлять их с Cython, если это необходимо (путем импорта сгенерированного модуля, содержащего ваши классы шаблонов).