Change language

Using C Codes in Python | Set 1

| | |

Let’s discuss the problem of accessing C code from Python. Because it is quite obvious that many of the built-in Python libraries are written in C. Thus, access to C is a very important part of Python’s interoperability with existing libraries. Python provides a rich API for programming in C, but there are many different ways to work with C.

Code # 1: [ work.c ] The C code we’re dealing with.

# include "math.h"

 

int gcd ( int x, int y)

{

int g = y; 

while (x" 0 )

{

g = x; 

x = y % x; 

y = g; 

}

return g; 

}

 

int divide ( int a , int b, int * remainder)

{

int quot = a / b; 

* remainder = a % b; 

return quot; 

}

 

double avg (double * a, int n)

{

int i; 

double total = 0.0

for (i = 0 ; i "n; i + + )

  {

total + = a [i]; 

}

return total / n; 

}

 
typedef struct Point
{

double x, y; 

} Point; 

 

double distance (Point * p1, Point * p2)

{

return hypot (p1 - " x - p2 - " x, p1 - " y - p2 - " y); 

}

The above code has various C programming features.

gcd ()
divide () - returning multiple values, one through a pointer argument
avg () - performing a data reduction across a C array
Point and distance () - involve C structures.

Let’s assume the above code is in a file named work.c and compiled into a library that can be linked to other C code. We now have a number of C functions that have been compiled into a shared library. So, we call functions entirely from Python without the need to write additional C code or use a third-party extension tool.

Using ctypes:
Will play in Python ctypes , but make sure the C code to be converted has been compiled into a shared library that is compatible with the Python interpreter (e.g. same architecture, word size, compiler, etc.).

Also, the libsample.so file has been placed in the same directory as work.py Let’s get to the work.py now.

Code # 2: Python module that wraps the resulting library to access it

# work. py

import ctypes

import os

 
# find file & # 39; libsample .so & # 39; in
# same directory as this file

_ file = ’libsample.so’

_ path = os.path.join ( ( * ( os.path.split ( (__ file __) [: - 1 ] + (_ file,)))

_mod = ctypes.cdll.LoadLibrary (_path)

Code # 3: Code Access

# int gcd (int, int)

gcd = _ mod.gcd

gcd.argtypes = (ctypes.c_int, ctypes.c_int)

gcd.restype = ctypes.c_int

 
# int division (int, int, int *)

_ divide = _ mod.divide

_ divide.argtypes = (ctypes.c_int, ctypes.c_int,

ctypes.POINTER (ctypes .c_int))

 

_ divide.restype = ctypes.c_int

 

def divide (x, y):

rem = ctypes.c_int ()

quot = _ divide (x, y, rem)

return quot, rem.value

 
# void avg (double *, int n)
# Define a special type for the argument & # 39; double * & # 39;

class DoubleArrayType:

  def from_param ( self , param):

 

< p> typename = type (param) .__ name__

 

if hasattr ( self , ’from_’ + typename):

return getattr ( self , ’from_’ + typename) (param)

 

elif isinstance (param, ctypes.Array):

  return param

 

else :

raise TypeError ( "Can ’t convert% s" % typename)

 

  # Cast from array.array objects

def from_array ( self , param):

i f param.typecode! = ’d’ :

raise TypeError ( ’ must be an array of doubles’ )

 

ptr, _ = param.buffer_info ()

return ctypes.cast (ptr, ctypes.POINTER (ctypes.c_double))

 

  # Cast from lists / tuples

def from_list ( self , param):

  val = ((ctypes.c_double) * len (param)) ( * param)

  return val

 

from_tuple = from_list

  

# Cast from numpy array

def from_ndarray ( self , param):

  return param.ctypes.data_as (ctypes.POINTER (ctypes.c_double))

  

DoubleArray = DoubleArrayType ()

_ avg = _ mod.avg

_avg.argtypes = (DoubleArray, ctypes.c_int)

_ avg.restype = ctypes.c_double

 

def avg (values):

return _ avg (values, len (values))

 
# struct Point {}

class Point (ctypes.Structure):

_ fields_ = [ ( ’x’ , ctypes.c_double), ( ’ y’ , ctypes.c_double)]

 
# double distance (point *, point *)

distance = _ mod.distance

distance.argtypes = (ctypes.POINTER (Point), ctypes.POINTER (Point))

distance.restype = ctypes.c_double

Now you can easily load the module and use the resulting C functions. See the next part — 

Shop

Learn programming in R: courses

$

Best Python online courses for 2022

$

Best laptop for Fortnite

$

Best laptop for Excel

$

Best laptop for Solidworks

$

Best laptop for Roblox

$

Best computer for crypto mining

$

Best laptop for Sims 4

$

Latest questions

NUMPYNUMPY

Common xlabel/ylabel for matplotlib subplots

12 answers

NUMPYNUMPY

How to specify multiple return types using type-hints

12 answers

NUMPYNUMPY

Why do I get "Pickle - EOFError: Ran out of input" reading an empty file?

12 answers

NUMPYNUMPY

Flake8: Ignore specific warning for entire file

12 answers

NUMPYNUMPY

glob exclude pattern

12 answers

NUMPYNUMPY

How to avoid HTTP error 429 (Too Many Requests) python

12 answers

NUMPYNUMPY

Python CSV error: line contains NULL byte

12 answers

NUMPYNUMPY

csv.Error: iterator should return strings, not bytes

12 answers


Wiki

Python | How to copy data from one Excel sheet to another

Common xlabel/ylabel for matplotlib subplots

Check if one list is a subset of another in Python

sin

How to specify multiple return types using type-hints

exp

Printing words vertically in Python

exp

Python Extract words from a given string

Cyclic redundancy check in Python

Finding mean, median, mode in Python without libraries

cos

Python add suffix / add prefix to strings in a list

Why do I get "Pickle - EOFError: Ran out of input" reading an empty file?

Python - Move item to the end of the list

Python - Print list vertically