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

psycopg2: insert multiple rows with one query

12 answers

NUMPYNUMPY

How to convert Nonetype to int or string?

12 answers

NUMPYNUMPY

How to specify multiple return types using type-hints

12 answers

NUMPYNUMPY

Javascript Error: IPython is not defined in JupyterLab

12 answers


Wiki

Python OpenCV | cv2.putText () method

numpy.arctan2 () in Python

Python | os.path.realpath () method

Python OpenCV | cv2.circle () method

Python OpenCV cv2.cvtColor () method

Python - Move item to the end of the list

time.perf_counter () function in Python

Check if one list is a subset of another in Python

Python os.path.join () method