I'm trying to use a C library (libmms, although that's not really important) with ctypes
; I wrote a small working C program first, but I seem to be having difficulty getting it to work with ctypes
Whenever I specify the return type (which is required, for I need it later) using test.restype = custom_t
things start to break.
My arguments (url
in specific) don't seem to work, or work very strangely (see the comments in C file). If I reduce the struct to just one entry (int a
) everything works as expected! (It breaks at about 3 or 4 lines, the original struct from libmms is much larger).
I've (obviously) tried adding argtypes
, muck about with various datatypes, etc., all to no avail...
Some simple example code to demonstrated the problem:
C library:
// Compiled with: clang -shared -Wl,-soname,test -o test.so -fPIC test.c
// Also tried gcc, with the same results
#include <stdio.h>
struct mmsh_t {
int a;
int b;
int c;
int d;
int e;
};
// Called as: test(None, None, b'Hello', 42)
// Outputs: mmsh_connect: (null)
struct mmsh_t *mmsh_connect (void *io, void *data, const char *url, int bandwidth) {
// Called as: test(42, b'Hello')
// Segfaults
// Curiously, when I output this with the Python code:
// test(b'Hello')
// It outputs: mmsh_connect: Hello
// Which is what I expected!
//struct mmsh_t *mmsh_connect (int io, const char *url) {
// Called as: test(b'Hello')
// Outputs: mmsh_connect:
//struct mmsh_t *mmsh_connect (const char *url) {
struct mmsh_t *this;
printf("mmsh_connect: %s\n", url);
return this;
}
Python code:
#!/usr/bin/env python3
# Python2 give the same results
import ctypes
class custom_t(ctypes.Structure):
_fields_ = [
('a', ctypes.c_int),
('b', ctypes.c_int),
('c', ctypes.c_int),
('d', ctypes.c_int),
('e', ctypes.c_int),
]
lib = ctypes.cdll.LoadLibrary('./test.so');
test = lib.mmsh_connect
test.restype = custom_t # <- Oh woe is this line!
test(None, None, b'Hello', 42)
#test(42, b'Hello')
#test(b'Hello')
What am I missing / doing wrong?