[Numpy-discussion] Example: How to use ctypes and link to a C library

Lou Pecora lou_boog2000@yahoo....
Thu Feb 14 14:14:03 CST 2008

I successfully compiled a shared library for use with
CTypes and linked it to an external library (Gnu
Scientific Library) on Mac OS X 10.4. I hope this
helps Mac people and anyone else who wants to use
CTypes to access their own C extensions and use other
C libraries in the process.  I want to thank several
people on this list who gave me many helpful
suggestions and asked me good questions.  I also want
to thank the several people who kept nudging me to try
CTypes even though I was reluctant.  It is much easier
than programming an extension all in C.   

Below are 4 files that enable building of a C shared
library in Mac OS X (10.4) that can be used with
CTypes to call a function from the Gnu Scientific
Library (a Bessel function program gsl_sf_bessel_J0). 
You can see that the idea is pretty simple.  The code
requires that you have ctypes (in site-packages) and
GSL (dynlib version in /usr/local/lib) or your desired
C library installed.  I suspect on other platforms
what will be different will be the make file.  I do
not know enough to provide Linux or Windows versions. 
I'm sorry.  

Note:  This works best if the libraries are shared
(e.g. the GSL library to use is the dynlib version). 
That way only the code that's needed is loaded when
the C functions are called from python.

Comments welcome. Of course, I am responsible for any
and all mistakes.  So, I make no guarantees or
warrenties.  These are examples and should not be used
where loss of property, life, or other dangers exist.

#==== Source code 'bess.c' ======================

#include <stdio.h>
#include "bess.h"
#include <gsl/gsl_sf_bessel.h> /* Must include the
header to define the function for compiler */

/* ---- test fcns ------------------------- */

#ifdef __cplusplus
extern "C" {

double J0_bess (double x) {
	/* Call the GSL Bessel function order 0 of the first
kind */
  double y = gsl_sf_bessel_J0 (x);
	/* Print the value right here */
  printf ("J0(%g) = %.18e\n", x, y);
  return y;

#ifdef __cplusplus

#==== Header file 'bess.h'  =====================

/* ---- Prototypes -------------------- */

#ifdef __cplusplus
extern "C" {

double J0_bess(double x);

#ifdef __cplusplus

#==== Make file 'bess.make'  ===================

# ---- Link to existing library in this directory
bess.so:  bess.o  bess.mak
	gcc -bundle -flat_namespace -undefined suppress -o
bess.so  bess.o  -lgsl

# ---- gcc C compile ------------------
bess.o:  bess.c bess.h bess.mak
	gcc -c bess.c -o bess.o
#==== Python file 'bess.py'  =======================


import numpy as N
import ctypes as C

# Put the name of your library in place of 'bess.so'
and the path to 
# it in place of the path below in load_library 
_bess = N.ctypeslib.load_library('bess.so',
_bess.J0_bess.restype = C.c_double
_bess.J0_bess.argtypes = [C.c_double]
def fcn_J0(x):
	return _bess.J0_bess(x)
x = 0.2
y = fcn_J0(x)
print "x, y: %e  %.18e" % (x, y)

#==== Typical output ===============
# The first line is printed from the shared library
function J0_bess
# The second line is from the python code that called
the shared lib. function

J0(0.2) = 9.900249722395765284e-01
x, y: 2.000000e-01  9.900249722395765284e-01

-- Lou Pecora,   my views are my own.

Be a better friend, newshound, and 
know-it-all with Yahoo! Mobile.  Try it now.  http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ 

More information about the Numpy-discussion mailing list