tags:

views:

2319

answers:

8

What would be the quickest way to construct a python binding to a C or C++ library?

(using windows if this matters)

+6  A: 

The quickest way to do this is using SWIG.

Ben Hoffstein
+2  A: 

I've never used it but I've heard good things about ctypes.

John
ctypes is pretty neat.
Calling C++ code from ctypes is going to be pretty hard, because of the name mangling.
Torsten Marek
Thorsten Marek: it's actually pretty easy, extern "C"
Florian Bösch
A: 

This paper, claiming python to be all a scientist needs, basically says: first prototype everything in Python. Then when you need to speed a part up, use SWIG and translate this part to C.

Yuval F
A: 

One of the official python documents (see link) contains details on extending python using c/c++. Even without the use of SWIG it's quite straightforward and works perfectly well on Windows.

Andrew Edgecombe
+1  A: 

Check out pyrex or cython. They're python-like languages for interfacing between C/C++ and python.

Jason Baker
+10  A: 

You should have a look at Boost.Python, here is the short introdution taken from their website: """ The Boost Python Library is a framework for interfacing Python and C++. It allows you to quickly and seamlessly expose C++ classes functions and objects to Python, and vice-versa, using no special tools -- just your C++ compiler. It is designed to wrap C++ interfaces non-intrusively, so that you should not have to change the C++ code at all in order to wrap it, making Boost.Python ideal for exposing 3rd-party libraries to Python. The library's use of advanced metaprogramming techniques simplifies its syntax for users, so that wrapping code takes on the look of a kind of declarative interface definition language (IDL). """

Ralph
Boost.Python is one of the more user-friendly libraries in Boost, for a simple function call API it is quite straightforward and provides boilerplate you'd have to write yourself. It's a bit more complicated if you want to expose an object-oriented API.
jwfearn
+14  A: 

I like ctypes a lot, swig always tended to give me problems. Also ctypes has the advantage that you don't need to satisfy any compile time dependency on python, and your binding will work on any python that has ctypes, not just the one it was compiled against.

Suppose you have a simple C++ example class you want to talk to:

#include <iostream>

class Foo{
    public:
        void bar(){
            std::cout << "Hello" << std::endl;
        }
};

Since ctypes can only talk to C functions, you need to provide those declaring them as extern "C"

extern "C" {
    Foo* Foo_new(){ return new Foo(); }
    void Foo_bar(Foo* foo){ foo->bar(); }
}

Next you have to compile this to a shared library

g++ -c -fPIC foo.cpp -o foo.o
g++ -shared -Wl,-soname,libfoo.so -o libfoo.so  foo.o

And finally you have to write your python wrapper

from ctypes import cdll
lib = cdll.LoadLibrary('./libfoo.so')

class Foo(object):
    def __init__(self):
        self.obj = lib.Foo_new()

    def bar(self):
        lib.Foo_bar(self.obj)

Once you have that you can use it like

f = Foo()
f.bar() #and you will see "Hello" on the screen
Florian Bösch
This is pretty much what boost.python does for you in a single function call.
Martin Beckett
ctypes is in the python standard library, swig and boost are not. Swig and boost rely on extension modules and are therefore tied to python minor versions which indepentent shared objects are not. building a swig or boost wrappers can be a pain, ctypes makes no build requirements.
Florian Bösch
boost relies on voodoo template magic and an entirely custom build system, ctypes relies on simplicity. ctypes is dynamic, boost is static. ctypes can handle different versions of libraries. boost cannot.
Florian Bösch
mgb: but you get me riled over boost, I'd encourage you to post an answer yourself. However to show boosts superiority over ctypes, it'll have to be the same example, less then 4 lines C++ wrapper code, less then 2 lines of build instructions and no lines of python, oh and fit it on one screen too.
Florian Bösch
Agreed: I too have troubles with swig and boost. You should make clear in your answer which ones are the files and which name one should get them.
Davide
A: 

You might find the suggestions in this similar question also helpful -> Prototyping hybrid Python code

Brendan