The lengthy intro:
I have been employing SWIG in a fairly lightweight context within my
application, wrapping an internal function that takes a component
reference and then executes it. This provides a highly simplified
interface within Python, were I can just call the function with the
component name and some arguments.
However, my application now has a functional SDK, and it's time for the
rubber to meet the road. The philosophy within the system (and the
SDK) is "code to an interface". This means that plug-ins for my
application must inherit from one or more C++ abstract base classes.
In order to directly afford Python programmers the ability to write
plug-ins for my application, I need to provide this same functionality
SWIG won't completely wrap C++ abstract base classes (rightly so),
leaving the wrappers with __init__() functions that throw an
AttributeError. So, I need an approach that allows the Python
environment to utilize these interfaces such that they are duck-typed
as a valid plug-in for my application.
The (imagined) approach:
The SWIG documentation talks about wrapping C++ abstract classes to the
extent that it (basically) can't be usefully done. It does not, from
what I've been able to find, talk about how it can be done.
So, the approach I'm going to try (and for which I would appreciate
some sage feedback) is to first create "shell" proxy classes in C++
that inherit from my SDK's interfaces. In a file called, for example,
"AbstractWrappers.h", where the inherited classes are those
with pure virtual methods, they would look something like
class ProxyPlugin : public SDK::Plugin
ProxyPlugin() : Plugin()
virtual void* get_interface(unsigned int interface_id)
class ProxyCommand : public SDK::Command
ProxyCommand() : Command()
virtual void execute(Context& ctx)
virtual void execute_without_item()
virtual void execute(const ItemRef& item)
// Convenience proxy
class ProxyCommandPlugin : public ProxyPlugin, public ProxyCommand
And so forth. The proxy classes would implement do-nothing versions of
the pure virtual methods, leaving the Python versions to override.
Then, in the SWIG interface file, I would wrap these proxy classes:
With the proxy classes wrapped, I would then turn on the "directors"
feature for each of them:
%module (naturalvar="1",directors="1") PySDK
Then, in the Python environment, I would inherit from the proxy classes
in order to create my Pythonic application plug-in classes:
class CommandPlugin(object, ProxyCommandPlugin)
Which would then allow me to interact with the Python CommandPlugin
class instance in C++ as though it were either a SDK::Plugin or an
Is this the best way to approach wrapping C++ abstract base classes, or
am I way off base? Does SWIG offer something more elegant than this?
I'd like an approach that makes plug-in writing within the scripting
environment as close as possible to that of the C++ (binary) case, so
if there are improvements to be made on this approach, I would greatly
appreciate knowing about it before I move forward.
All my thanks.
Render me gone, |||
The world needs more cults. They attract stupidity like a
magnet attracts metal, and they're self cleaning.