2

I need to wrap a C function of interface

double foo(double)

to python, so that in python console

>>foo_py(2.9)

should give me the double value of foo(2.9). Eventually, I use the exported foo_py in scipy.

I have been looking for the simplest way to wrap such a C function.There are certainly many related posts on stackoverflow, but they are dated a couple of years ago and at this moment I am looking for an updated answer for my specific demand. Thanks.

[EDIT] For information, I tried with C extension using PyObj etc. The documentation on this seems lacking. I also tried with Boost.Python that wraps C++ functions to Python. Here I need to wrap C functions (in order to avoid naming demangling issues, etc).

zell
  • 9,830
  • 10
  • 62
  • 115
  • 2
    That should be pretty straight forward with ctypes: http://stackoverflow.com/a/145649/1470749 – 101 Apr 27 '15 at 04:54
  • @figs Thanks. The link you give me seems very nice. Let me check it out while waiting for others' response. – zell Apr 27 '15 at 05:04
  • @fig Strange. The wrapped functon returns me 0, always. My code is like his: import ctypes from ctypes import cdll lib=cdll.LoadLibrary("./libfoo.so") lib.foo_r.argtypes=(ctypes.c_double,) lib.foo_r.restypes=ctypes.c_double print lib.foo_r(9) – zell Apr 27 '15 at 06:58
  • 1
    Strange, you'd have to post all Python and C code for us to check it. – 101 Apr 27 '15 at 07:00
  • @fig Thanks for your help. My C code is large. python code posted as comments above. I may open a new post later, but now I use Everlisle's solution. It works. Thanks. – zell Apr 27 '15 at 07:04

1 Answers1

3

Here is a simple example of how to do it:

test.c

#include <Python.h>

static PyObject* foo(PyObject* self, PyObject* args) {
  double d;
  PyArg_ParseTuple(args, "d", &d);
  return Py_BuildValue("d", d);
}

// Bind python function to C function
static PyMethodDef simplemodule_methods[] = {
  {"foo_py", foo, METH_VARARGS},
  {NULL, NULL, 0}
};

// Initialize module
void inittest() {
  (void) Py_InitModule("test", simplemodule_methods);
}

test.py

from test import *
print foo_py(2.9) # will output 2.9

Compile with

gcc -shared -fPIC -I/usr/include/python2.7 -o test.so test.c

Run with

python test.py

EvenLisle
  • 4,672
  • 3
  • 24
  • 47