Using Cython as a Boost.Python replacement for C++ libraries?

1,082 views
Skip to first unread message

Skip Montanaro

unread,
Jul 2, 2015, 1:44:34 PM7/2/15
to cython...@googlegroups.com
Awhile ago I asked on comp.lang.python about using cffi as an interface to C++ libraries. Lele Gaifax pointed me to Cython. I glanced quickly at the doc page Lele referenced:


then got onto other things, and let that lay for awhile, but just bumped into some bogosities in some Boost.Python wrappers which made me think I should take a more serious look.

I just reread the above page. It's not at all clear to me how I'm supposed to create an interface to an existing C++ library. I don't want to compile the source to the library, just reveal some classes (and part of their public interfaces) to my Python code. I've used Cython up to this point to lightly boost some existing Python code, but haven't yet used it as a replacement for writing an extension module. I have pretty much zero experience with setup.py, even less with C++ or Boost.Python. I'm just looking for an easier way to write an extension module interfacing to some C++ libraries. Extension modules I can write, but I'm lazy, and was hoping Cython would offer a more Pythonic alternative. Any tutorials which reference this process appreciated. Maybe something like the Rectangle.cpp/h example which assumes that the C++ class code is external? I suspect it's right in front of my face, but I'm not looking at things in the right way.

Thanks,

Skip Montanaro

Sturla Molden

unread,
Jul 2, 2015, 2:08:46 PM7/2/15
to cython...@googlegroups.com
If you have used Cython you have written an extension module in Cython. It
is the only thing Cython can do.

Generally there are (at least) two ways of using C++ callable code from
Cython and exposing it to Python:

One it to declare your C++ classes as "cdef cppclass" and thus expose their
interface to Cython. Then you can write your own "cdef class" which exposes
this functionality to Python. The common design is to call new in __init__
and call del in __dealloc__. The lifetime of your C++ class is then linked
to the lifetime of your Cython class when using it from Python. This is the
method I would recommend.

The other way of using C++ from Cython is to wrap all the C++ inside C
callable functions. This is more tedious, but works well too. Another
drawback is that you must manually take care of the conversion from C++
standard exceptions to Python exceptions.

In my C++ rewrite of scipy.spatial.cKDTree to C++ (some of it merged in
SciPy 0.16, the rest in a PR for 0.17) I ended up doing the latter. If I
had not done the conversion gradually in multiple PRs, I would probably
have gone for the first solution.


Sturla

Chris Barker - NOAA Federal

unread,
Jul 2, 2015, 7:59:52 PM7/2/15
to cython...@googlegroups.com
Skip, you may want to give Xdress a try for auto-wrapping your c++ with Cynthon.

Chris

Sent from my iPhone
> --
>
> ---
> You received this message because you are subscribed to the Google Groups "cython-users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to cython-users...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Robert Bradshaw

unread,
Jul 2, 2015, 11:59:26 PM7/2/15
to cython...@googlegroups.com
On Thu, Jul 2, 2015 at 11:08 AM, Sturla Molden <sturla...@gmail.com> wrote:
> If you have used Cython you have written an extension module in Cython. It
> is the only thing Cython can do.
>
> Generally there are (at least) two ways of using C++ callable code from
> Cython and exposing it to Python:
>
> One it to declare your C++ classes as "cdef cppclass" and thus expose their
> interface to Cython. Then you can write your own "cdef class" which exposes
> this functionality to Python. The common design is to call new in __init__
> and call del in __dealloc__. The lifetime of your C++ class is then linked
> to the lifetime of your Cython class when using it from Python.

+1

Note that classes with nullary constructors can be used as members of
cdef classes directly, no need to manually call new/del at all. Also,
__cinit__ is always called exactly once, __init__ may not be.

> This is the
> method I would recommend.
>
> The other way of using C++ from Cython is to wrap all the C++ inside C
> callable functions. This is more tedious, but works well too. Another
> drawback is that you must manually take care of the conversion from C++
> standard exceptions to Python exceptions.

Before Cython had (decent) C++ support, creating a C shim was the only
option. Now I can't imagine any reason one would want to go this route
(unless it uses crazy C++ features, in which case you could even
create a "nicer" C++ API for some parts rather than being stuck with
just C).

> In my C++ rewrite of scipy.spatial.cKDTree to C++ (some of it merged in
> SciPy 0.16, the rest in a PR for 0.17) I ended up doing the latter. If I
> had not done the conversion gradually in multiple PRs, I would probably
> have gone for the first solution.
>
>
> Sturla
>
Reply all
Reply to author
Forward
0 new messages