Create a gist now

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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
http://www.johnstowers.co.nz/blog/index.php/2011/07/15/interfacing-python-c-opencv-via-ctypes/
#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;
}
void
test_data_print(char *data, int len)
{
int i;
for (i = 0; i < len; i++)
printf("%x (%c),",data[i],data[i]);
printf("\n");
}
void
test_get_data_nulls_out(char **data, int *len)
{
*data = test_get_data_nulls(len);
}
void
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);
void
test_data_print(char *data, int len);
void
test_get_data_nulls_out(char **data, int *len);
void
test_get_fixed_array_size_2(double *data);
all: test libtest.so testmodule
libtest.so: libtest.c
$(CC) -Wall -g -fPIC -shared -o $@ $? -lc
test: test_main.c libtest.o
$(CC) -o $@ $?
testmodule: testmodule.c
python setup.py build
clean:
rm -f test libtest.o libtest.so *.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"},
{NULL, NULL, 0, NULL},
};
PyMODINIT_FUNC
inittestmodule(void)
{
(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, "..", "libtest.so"))
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
lib.test_data_print(data,l)
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
lib.test_data_print(data2,l2)
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)()
func(data)
x,y = data
print "array ", x,y
import testmodule
data = testmodule.test_get_data_nulls()
print len(data), data
print
data = testmodule.test_get_data(12)
print len(data), data
@mwpcheung

This comment has been minimized.

Show comment
Hide comment
@mwpcheung

mwpcheung Jun 29, 2018

how to alloc bytes buffer from python side?

how to alloc bytes buffer from python side?

@deasuke

This comment has been minimized.

Show comment
Hide comment
@deasuke

deasuke Jul 11, 2018

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

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