0

I have two custom-written C routines that I would like to use as a part of a large Python application. I would prefer not to rewrite the C code in pure Python (or Cython, etc.), especially to maintain speed.

What is the cleanest, easiest way that I can use my C code from my Python code? Or, what is the cleanest, easiest way for me to wrap my C code for use in my Python source?

I know "cleanest" and "easiest" will attract opinions, but I really just need some good options for using custom pre-written code, versus many of the other answers/tutorials which describe how to use full-on C libraries as CPython extensions.

EDIT:

Cython and ctypes have both been suggested. Which is a better choice in my case? Each of the two routines I mentioned originally are very computationally intensive. They are used for image calculations and reconstructions, so my plan is to build a Python application around their use (with other functionality in mind that I already have in Python) with the C code run as needed for processing.

bearplane
  • 700
  • 1
  • 9
  • 22

2 Answers2

1

Use cython to wrap your C code. In other words, create a CPython extension using Cython, that calls your C code.

nosklo
  • 217,122
  • 57
  • 293
  • 297
  • Is this still a good idea if these C functions are very large and computationally intensive? – bearplane Jul 03 '18 at 18:47
  • I don't see why not? You will be calling your C code as it is... Who cares if it is intensive or not? I don't understand your concern at all @questionable_code – nosklo Jul 03 '18 at 18:48
  • I apologize. I was trying to infer which of the two routes (cython or ctypes) I should try with more confidence, as the latter was suggested below. – bearplane Jul 03 '18 at 18:58
  • Cython code is maintainable high level code that when compiled gets converted to C and linked as a binary extension to python - it is the most polite solution and very performant. ctypes feels like a hack next to cython, which will produce a full enterprise-quality python extension. @questionable_code – nosklo Jul 03 '18 at 19:06
  • @questionable_code: If done right, Cython does the same job as a raw C extension, with a lot less work. You can inspect the generated C/C++ code to see if it's being done mostly sanely (the generated code tends to be quite verbose, but in ways that the compiler's optimizer cleans it up in the final extension). – ShadowRanger Jul 03 '18 at 19:15
  • Will update with an "accept" if this works out for what I'm dealing with. Thanks everyone! – bearplane Jul 03 '18 at 19:50
0

You can call C directly from python. Example pulled from here: https://www.csestack.org/calling-c-functions-from-python/

from ctypes import *
libCalc = CDLL("./libcalci.so")

#call C function to check connection
libCalc.connect() 

#calling randNum() C function
#it returns random number
varRand = libCalc.randNum()
print "Random Number:", varRand, type(varRand)

#calling addNum() C function
#it returns addition of two numbers
varAdd = libCalc.addNum(20,30)
print "Addition : ", varAdd
eatmeimadanish
  • 3,809
  • 1
  • 14
  • 20
  • Note that this works best when a *single* call via `ctypes` does most of the work, *and* the work is significant; if you're making lots of small calls doing very little work, `ctypes` introduces non-trivial overhead that true C extensions can avoid. – ShadowRanger Jul 03 '18 at 18:43
  • @ShadowRanger so is this a decent path if my routines are very computationally intensive and large? – bearplane Jul 03 '18 at 18:48
  • If the work isn't complicated you are better off just writing it in Python in the first place rendering this question moot. I inferred that the c code was complex and heavy, ctypes is the best way to go in that regard. – eatmeimadanish Jul 03 '18 at 18:55
  • @questionable_code: Yeah, `ctypes` overhead is typically in the hundreds of nanoseconds to single digit microseconds at worst; if you're doing even a millisecond's worth of work at the C layer per call, the `ctypes` overhead is pretty meaningless. The trick is with libraries that expose lots of small calls that are useful to Python, but not easy to reimplement in Python efficiently. Stuff like the simple GMP math functions; a pain to reimplement, but trivial work relative to `ctypes` overhead (in this particular case, `gmpy2` is the way to go, but similar libs without wrappers exist). – ShadowRanger Jul 03 '18 at 19:13