A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://www.geeksforgeeks.org/python/using-c-codes-in-python-set-1/ below:

Using C codes in Python | Set 1

Using C codes in Python | Set 1

Last Updated : 11 Jul, 2025

Prerequisite:

How to Call a C function in Python

Let's discuss the problem of accessing C code from Python. As it is very evident that many of Python’s built-in libraries are written in C. So, to access C is a very important part of making Python talk to existing libraries. There is an extensive C programming API that Python provides but there are many different to deal with C.

Code #1 :

[

work.c

] C-Code that we are dealing.

Python3 1==
#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);
}

Above code has different 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 that the code above is found in a file named

work.c

and it has been compiled into a library

libsample

that can be linked to other C code. Now, we have a number of C functions that have been compiled into a shared library. So, we call the functions entirely from Python without having to write additional C code or using a third-party extension tool.

Using ctypes :

Python

ctypes

will come to play but make sure the C code, that is 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.). Further the

libsample.so

file has been placed in the same directory as the

work.py

. Let's understand

work.py

now.

Code #2 : Python module that wraps around resulting library to access it Python3 1==
# work.py
import ctypes
import os

# locating the 'libsample.so' file in the
# 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 : Accessing code Python3 1==
# int gcd(int, int)
gcd = _mod.gcd
gcd.argtypes = (ctypes.c_int, ctypes.c_int)
gcd.restype = ctypes.c_int

# int divide(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 'double *' argument
class DoubleArrayType:
    def from_param(self, param):
        
        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):
        if 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 a 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, one can easily load the module and use the resulting C functions. See the next part -

Using C codes in Python | Set 2

.



RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4