As you say, Cython doesn't really support this.
I think by far the simplest approach is just to manually generate a bunch of Cython files using string substitution. Start with a "foowrapper.pxi.src" file (name as you wish...):
cdef class PyFoo_{T}:
cdef Foo[{T}] *thisptr
def __cinit__(self, param):
self.thisptr = new Foo[{T}](param)
# etc
Next, run it through a simple program (may as well be Python) to load the file, do the string substitution, and save the file again under a new name. The key line is just:
output = code.format(T=T) # where T is a string with a C++ class name
# e.g. "int" or "std::vector<double>"
(There's obviously a bit of code relating to loading and saving that I've skipped out of laziness)
Then, in your Cython file you just "include" the generated files for each class. The "include" command in Cython is a literal textual include (like the C preprocessor) and expects a .pxi file:
cdef extern from "header.h":
cdef cppclass Foo[T]:
Foo(T param)
# ...
include "foowrapper_int.pxi"
include "foowrapper_vectordouble.pxi
# etc
You have to pick the classes to generate at compile time, but this is unavoidable (templates are a compile-time feature), so you're never going to be able to generate them dynamically from a Python scripting environment since the corresponding C++ class won't be generated.
Other options
A couple of other options are worth brief consideration. First, you could inherit Foo<T>
from a base class (say FooBase
) which doesn't depend on the template parameter. You'd then wrap FooBase
in Cython (generating constructor-like functions for the cases you care about). This is only really viable if the functions you want to call don't have arguments that depend on the template type. Obviously this also involves changing the C++ code.
The section option is to look at a different way of wrapping. Boost Python will certainly support this natively (but comes with its own disadvantages). I imagine SIP/SWIG would also cope (but I don't know). You can could fairly cleanly mix-and-match these with Cython if necessary (by importing the generated module containing your template classes).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…