I'd like to wrap the following c function bar() in python 2.x and invoke it via the ctypes module, both on Linux and Windows:
#include <stdio.h>
#ifdef FOO_DLL
#define FOO_API __declspec(dllexport)
#else
#define FOO_API extern
#endif
FOO_API unsigned int bar(const void* data, unsigned int len)
{
printf("%p (%d bytes)\n", data, len);
return len;
}
To compile the shared library I use scons:
import sys
env = Environment()
if sys.platform == 'win32':
env.Append(CFLAGS=['-DFOO_DLL'])
env.SharedLibrary('foo', ['foo.c'])
Finally I load the respective shared lib and invoke the function:
import sys
import struct
from ctypes import *
if sys.platform == 'win32':
libfoo = windll.LoadLibrary('foo')
else:
libfoo = cdll.LoadLibrary('./libfoo.so')
data = struct.pack('BBB', 0, 1, 2)
libfoo.bar(data, len(data))
To my surprise this seems to work flawlessly under Linux, but on Windows the code throws an error that makes me suspects that this isn't the proper way to do things:
$ python foo.py
00B520C4 (3 bytes)
Traceback (most recent call last):
File "foo.py", line 11, in <module>
libfoo.bar(data, len(data))
ValueError: Procedure probably called with too many arguments (8 bytes in excess)
What would be the right approach?
On Linux (Ubuntu 10.10 64bit) I'm using Python 2.6.6, gcc 4.4.5 and on Windows (XP 32bit, in a VirtualBox) Python 2.7.1 and VS2010 Express.