Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is wrapping C++ library with ctypes a bad idea?

I read through the following two threads on wrapping C library and C++ library, I am not sure I get it yet. The C++ library I am working with does use class and template, but not in any over-sophisticated way. What are issues or caveats of wrapping it with ctypes (besides the point that you can do so in pure python etc)?

PyCXX , Cython and boost::python are three other choices people mentioned, is there any consensus which one is more suitable for C++?

Thanks

Oliver

like image 565
Oliver Avatar asked Jan 31 '12 17:01

Oliver


People also ask

Can ctypes be used with C++?

ctypes is the de facto standard library for interfacing with C/C++ from CPython, and it provides not only full access to the native C interface of most major operating systems (e.g., kernel32 on Windows, or libc on *nix), but also provides support for loading and interfacing with dynamic libraries, such as DLLs or ...

What is ctypes CDLL?

ctypes is a foreign function library for Python. It provides C compatible data types, and allows calling functions in DLLs or shared libraries. It can be used to wrap these libraries in pure Python.

How do you wrap a C code in Python?

To wrap this manually, we need to do the following. First, write a Python-callable function that takes in a string and returns a string. Second, register this function within a module's symbol table (all Python functions live in a module, even if they're actually C functions!)

What is C_char_p?

c_char_p is a subclass of _SimpleCData , with _type_ == 'z' . The __init__ method calls the type's setfunc , which for simple type 'z' is z_set . In Python 2, the z_set function (2.7.


2 Answers

In defence of boost::python, given Alexander's answer on ctypes:

Boost python provides a very "c++" interface between c++ and python code - even doing things like allowed python subclasses of c++ classes to override virtual methods is relatively straightforward. Here's a potted list of good features:

  • Allow virtual methods of C++ classes to be overridden by python subclasses.
  • Bridge between std::vector<>, std::map<> instances and python lists and dictionaries (using vector_indexing_suite and map_indexing_suite)
  • Automatic sharing of reference counts in smart pointers (boost::shared_ptr, etc) with python reference counts (and you can extend this to any smart pointer).
  • Fine grained control of ownership when passing arguments and returning values from functions.

Basically, if you have a design where you want to expose a c++ interface in a way faithful to the language, then boost::python is probably the best way to do it.

The only downsides are increased compile time (boost::python makes extensive use of templates), and sometimes opaque error messages if you don't get things quite right.

like image 114
James Avatar answered Nov 15 '22 17:11

James


For C++ a library to be accessible from Python it must use C export names, which basically means that a function named foo will be accessible from ctypes as foo.

This can be achieved only by enclosing the public interface with export C {}, which in turn disallows function overloading and templates therein (only the public interface of the library to be wrapped is relevant, the inner workings are not and may use any C++ features they like).

Reason for this is that C++ compilers use a mechanism called name mangling to generate unique names for overloaded or templated symbols. While ctypes would still find a function provided you knew its mangled name, the mangling scheme depends on the compiler/linker being used and is nothing you can rely on. In short: do not use ctypes to wrap libraries that use C++ features in their public interface.

Cython takes a different approach. It aids you at building a C extension module that does the interfacing with the original library. Therefore, linking to the C++ library is done by the regular C++ linkage mechanism, thus avoiding the aforementioned problem. The trouble with Cython is that C extension libraries need to to be recompiled for every platform, but anyway, this applies to the C++ library to be wrapped as well.

Personally, I'd say that in most cases the time to fire up Cython is a time that is well-spent and will eventually pay off in comparison to ctypes (with an exception for really simple Cish interfaces).

I don't have any experience with boost.python, so I can't comment on it (however, I don't have the impression that it is very popular either).

like image 25
Alexander Gessler Avatar answered Nov 15 '22 17:11

Alexander Gessler