Created
May 25, 2011 07:09
-
-
Save nzjrs/990493 to your computer and use it in GitHub Desktop.
Python ctypes example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import testmodule | |
data = testmodule.test_get_data_nulls() | |
print len(data), data | |
data = testmodule.test_get_data(12) | |
print len(data), data |
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
how to alloc bytes buffer from python side?