开发者

Extending python with C module

开发者 https://www.devze.com 2023-01-12 08:29 出处:网络
So I have a C program to interface with an i2c device. I need to interface to that device from python. I\'m just wondering if it\'s worth porting the program into a python module or if the amount of e

So I have a C program to interface with an i2c device. I need to interface to that device from python. I'm just wondering if it's worth porting the program into a python module or if the amount of effort involved in porting won't outweigh just executing the program using subprocess. I know I'm sure it's different for every application, but I'd like to know if it's even worth my time to learn the python C extensions and port this program.

Update: I have full access to the source of both the C as well as the python. But there is already substantial work 开发者_开发问答done on the python side and I'd like to keep changes to that as minimal is possible, if that matters. And I'd also like to minimize the changes that have to be made to the C. It's doable, but I didn't write it and it involves a lot of by addressing that I'd rather not have to redo.


There are many ways you can proceed -- the Python C API, which seems to be the one you're considering, but also SWIG, Cython, ctypes... as long as your existing C code can be made into a library (with functions callable "from the outside"), you have a wealth of options. Personally, I'd recommend Cython -- it's looking more and more as a broad subset of Python, extended just enough to allow effective compilation into machine code and direct calling of functions from C libraries.


One of the first Python programs I wrote was a script that called functions from a C library, which sounds close to what you're doing. I used ctypes, and I was impressed as to how easy it was: I could access each library function from python by writing just a few lines of python (no C at all!). I'd tried the Python C API before, and it required a lot more boilerplate. I havent tried SWIG or Cython.


Don't use the Python C API, there are much easier alternatives, most notably cython.

cython is a Python-like language, which compiles into C code for the Python c library. Basically it's C with Python syntax and features (e.g. nice for loops, exceptions, etc.). cython is clearly the most recommendable way to write C extensions for python.

You might also want to take a look at ctypes, a module to dynamically load C libraries and call functions from them. If your i2c-code is available as shared library, you can get away with no native binding at all, which eases development and distribution.


I've had good luck using ctypes. Whatever you choose, though, you may not gain any time this time but the next time around your effort will be much faster than doing the whole thing in C.


I would recommend ctypes using a shared library. It would be a good idea however to don't rely on complex types like structs in your C API. Using a pseudo-OOP approach is the simplest to map over to Python.

E.g.

foo_t* foo_new(void);
int foo_bar(foo_t*, int);
int foo_baz(foo_t*, int);
void foo_free(foo_t*);

Here, you could use ctypes native stuff. E.g. c_void_p for your object handle and c_int. c style strings are also supported with create_string_buffer (or something like that).

0

精彩评论

暂无评论...
验证码 换一张
取 消