Skip to content

Instantly share code, notes, and snippets.

Created May 25, 2011 07:09
Show Gist options
  • Save nzjrs/990493 to your computer and use it in GitHub Desktop.
Save nzjrs/990493 to your computer and use it in GitHub Desktop.
Python ctypes example
Interfacing python + c + opencv via ctypes
This is an example showing how to access
image data, that is consisting of non null-terminated,
non-string char * arrays.
More information is available here
#include <stdlib.h>
#include <stdio.h>
char *
test_get_data(unsigned int len)
return malloc(len);
char *
test_get_data_nulls(int *len)
*len = 5;
char *d = malloc(5);
d[0] = 'a';
d[1] = 'b';
d[2] = '\0';
d[3] = 'c';
d[4] = '\0';
return d;
test_data_print(char *data, int len)
int i;
for (i = 0; i < len; i++)
printf("%x (%c),",data[i],data[i]);
test_get_data_nulls_out(char **data, int *len)
*data = test_get_data_nulls(len);
test_get_fixed_array_size_2(double *data)
data[0] = 1.0;
data[1] = 2.0;
char *
test_get_data(unsigned int len);
char *
test_get_data_nulls(int *len);
test_data_print(char *data, int len);
test_get_data_nulls_out(char **data, int *len);
test_get_fixed_array_size_2(double *data);
all: test testmodule libtest.c
$(CC) -Wall -g -fPIC -shared -o $@ $? -lc
test: test_main.c libtest.o
$(CC) -o $@ $?
testmodule: testmodule.c
python build
rm -f test libtest.o *.pyc
rm -rf build
from distutils.core import setup, Extension
module1 = Extension('testmodule', sources = ['testmodule.c', 'libtest.c'])
setup (name = 'PackageName',
version = '1.0',
description = 'This is a demo package',
ext_modules = [module1])
#include <stdio.h>
#include "libtest.h"
int main (void)
char *data, *data2;
int len, len2;
data = test_get_data_nulls(&len);
test_data_print(data, len);
test_get_data_nulls_out(&data2, &len2);
test_data_print(data2, len2);
#include <Python.h>
#include "libtest.h"
static PyObject* wrap_test_get_data_nulls(PyObject* self)
char *s;
int l;
s = test_get_data_nulls(&l);
return PyString_FromStringAndSize(s, l);
static PyObject* wrap_test_get_data(PyObject* self, PyObject* args)
char *s;
unsigned int l;
if (!PyArg_ParseTuple(args, "I", &l))
return NULL;
s = test_get_data(l);
return PyString_FromStringAndSize(s, l);
static PyMethodDef ModuleMethods[] =
{"test_get_data", wrap_test_get_data, METH_VARARGS, "Get a string of variable length"},
{"test_get_data_nulls", wrap_test_get_data_nulls, METH_NOARGS, "Get a string of fixed length with embedded nulls"},
(void) Py_InitModule("testmodule", ModuleMethods);
import os.path
from ctypes import *
me = os.path.abspath(os.path.dirname(__file__))
lib = cdll.LoadLibrary(os.path.join(me, "..", ""))
func = lib.test_get_data_nulls
func.restype = POINTER(c_char)
func.argtypes = [POINTER(c_int)]
l = c_int()
data = func(byref(l))
print data,l,data.contents
func_out = lib.test_get_data_nulls_out
func_out.argtypes = [POINTER(POINTER(c_char)), POINTER(c_int)]
func.restype = None
l2 = c_int()
data2 = POINTER(c_char)()
func_out(byref(data2), byref(l2))
print data2,l2,data2.contents
print "equal ", data[0]==data2[0], data[1]==data2[1], data[2]==data2[2], data[3]==data2[3], data[4]==data2[4]
func = lib.test_get_fixed_array_size_2
func_out.argtypes = [POINTER(c_double)]
func.restype = None
data = (c_double * 2)()
x,y = data
print "array ", x,y
import testmodule
data = testmodule.test_get_data_nulls()
print len(data), data
data = testmodule.test_get_data(12)
print len(data), data
Copy link

how to alloc bytes buffer from python side?

Copy link

deasuke commented Jul 11, 2018

You can define a function which calls malloc() in your shared object and call it through ctypes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment