I’m trying to add a python callback to a C++ library as illustrated:
template<typename T> void doCallback(shared_ptr<T> data) {
PyObject* pyfunc; //I have this already
PyObject* args = Py_BuildValue("(O)", data);
PyEval_CallObject(pyfunc,args);
}
This fails because data hasn’t gone through swig, and isn’t a PyObject.
I tried using:
swigData = SWIG_NewPointerObj((void*)data, NULL, 0);
But because its a template, I don’t really know what to use for the second parameter. Even if I do hard code the ‘correct’ SWIGTYPE, it usually segfaults on PyEval_CallObject.
So my questions are:
-
Whats the best way to invoke swig
type wrapping? -
Am I even going in the right
direction here? Directors looked
promising for implementing a
callback, but I couldn’t find an
example of directors with python.
Update: The proper wrapping is getting generated. I have other functions that return shared_ptrs and can call those correctly.
My first answer misunderstood the question completely, so let’s try this again.
Your central problem is the free type parameter
Tin the definition ofdoCallback. As you point out in your question, there’s no way to make a SWIG object out of ashared_ptr<T>without a concrete value forT:shared_ptr<T>isn’t really a type.Thus I think that you have to specialize: for each concrete instantiation of
doCallbackthat the host system uses, provide a template specialization for the target type. With that done, you can generate a Python-friendly wrapping ofdata, and pass it to your python function. The simplest technique for that is probably:…though this can only work if your Python function doesn’t save its argument anywhere, as the
shared_ptritself is not copied.If you do need to retain a reference to
data, you’ll need to use whatever mechanism SWIG usually uses to wrapshared_ptr. If there’s no special-case smart-pointer magic going on, it’s probably something like:Regardless, you then you have a Python-friendly SWIG object that’s amenable to
Py_BuildValue().Hope this helps.