Use C Library In Python using C Types

Do you have a C library which needs to be used for Python Devs. well, you can have python bindings which loads the C library and use those functions using C types.

Here I am giving small demo, my C library has add and multiply functions like this.
demo.c
=======
#include
int add(int,int);
float mul(float,int);

int add(int a,int b)
{
return a+b ;
}

float mul(float a,int b)
{
return a*b ;

}

Lets Compile this program as Shared Library
 # gcc -c -Wall -Werror -fpic demo.c 
The above step produces demo.o, Lets have shared lib now

On Linux
 # gcc -shared -o libcalc.so demo.o
On Mac
# gcc -shared -o libcalc.dylib demo.o

Lets Use this libcalc.so or libcalc.dynlib in Python now, using the C types. 

api.py
=========================
import ctypes
from ctypes.util import find_library
from ctypes import sizeof

'''this will find library name . In Linux you have libcalc.so , in Mac libcalc.dynlib'''
so_file_name = find_library("calc")

if so_file_name is None:
    raise Exception("libcalc.so not found")
try:
    client = ctypes.CDLL(so_file_name, ctypes.RTLD_GLOBAL, use_errno=True)
except OSError:
    raise ImportError("cannot load {0}. please set LD_LIBRARY_PATH \                              variable".format(so_file_name))

def calc_func(method,rettype,*argtypes):
    '''
    create a func belonging to calc.so
    '''
    return ctypes.CFUNCTYPE(rettype,*argtypes,use_errno=True)((method,client))

''' Define python functions for each C function in libcalc.so  
we have add,mul functions in our libcalc.so.  '''

py_add = calc_func('add',ctypes.c_int, ctypes.c_int,ctypes.c_int)

py_mul = calc_func('mul',ctypes.c_float,ctypes.c_float,ctypes.c_int)


Now we have api.py which loads the C library and bridges to python.

main.py which uses api.py in python style
==================
import api
add_output = api.py_add(2,3)
print(add_output)
mul_output = api.py_mul(float(5.5),10)
print(mul_output)

#python main.py 



Note: What if you have C++ library, well its better you use extern "C" and write a C wrapper which intern calls C++.


No comments: