public
Description: Good code.
Homepage: http://www.ralree.com
Clone URL: git://github.com/hank/life.git
life / oscon / 2008 / sessions / SWIG.rdoc
100644 65 lines (56 sloc) 3.026 kb

OSCON 2008, Session 10: Python, C++, and SWIG

Interfacing

  • Python is C-extensible
  • Calling code doesn’t need to know if it’s calling Python or C
  • You can deal with objects, raise Python exceptions, call python functions/methods, play with lists and dictionaries, etc.

Extension Modules

  • Implemented as shared objects
  • Placed in the Python path
  • Used with the Python import statement
  • Python calls an init function in the C library

But

  • You still have to deal with the bas parts of C/C++
  • Yet, we can minimize it to just things that need massive optimization
  • Unit testing can happen from the Python side

Bad?

  • Can be tedious to make this stuff
  • You have to write a Python wrapper for every function you want to access
    • Convert input params
    • Call target function
    • Checking for errors
    • Raising Exceptions
    • Converting the return value to something acceptable in Python
  • Create Python versions of C constants
  • C structs, variables, C++ classes
  • Write an initialization function
  • Total yuck. I wonder if there’s a better way to do this.…

SWIG

  • OMG!
  • Simplified Wrapper Interface Generator
  • Automates work creating modules, removes tedium
  • Allows you to glue C/C++ to Python, and partition your application to the language’s strengths
  • You can think of it as a compiler, it reads C/C++ declarations and writes C code implementing the extension
  • Support for structs, classes, functions, constants, etc.
  • Lots of language extensions
  • Understands the C++ Class hierarchy
  • Does appropriate type checking of input params, etc.
  • Can generate code for C++ templates
  • Can generate code to override C++ virtual methods in Python classes

Many things out of the box

  • You can customize lots of stuff it does
    • %typemap: controls what C code is generated in wrapper functions that receive or return objects of certain types
    • %extend: Can add new methods to a wrapped class that don’t necessarily exist in the C++ class
    • %inline: Add new C functions that will automatically be wrapped
    • %pythoncode: Emit custom Python code into the wrapper for the current class, or append or prepend it to the Python proxy function
  • There’s more too!
  • You can define a macro that’s multiple lines without doing line continuation

Modes of operation for Python targets

  • Generate nothing but the extension module (just creates the C wrapper)
  • Generate the above, and the proxy module. Useful when wrapping C++. Makes the Python classes that look and act like the C++ ones.
  • You can make class-based API wrappers for plain old C functions.
  • the .i file makes a python script and a c/cpp file. Then you compile it into a shared object

Why not use SWIG

  • It doesn’t generate optimized code
  • Classes are flattened to a collection of wrapped functions, with OO-ness added back on by the Proxy classes. Hand-coded module would probably use extension types (classes) instead.

But then again, we should use it

  • Saves time and lets you focus on the good stuff