ctypes help
Python
python at bladeshadow.org
Fri Nov 17 17:11:29 EST 2017
Hello Pythonistas,
I'm starting to play with ctypes, as I'd like to provide Python
interfaces to a C/C++ library I have. For now I'm just messing with a
very simple piece of code to get things sorted out. I'm working with
this example C++ library, which just wraps a call to stat():
-=-=-=-=-=-=-
$ cat stat.cc
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
extern "C" int my_stat(const char *path, struct stat *st)
{
return stat(path, st);
}
-=-=-=-=-=-=-
Then I compile this to a shared object with g++ -shared -fPIC in /tmp. My
attempt to wrap that looks as follows:
-=-=-=-=-=-=-
#!/usr/bin/python
import ctypes
libc = ctypes.CDLL("/tmp/my_stat.so")
stat = libc.my_stat
class Timespec(ctypes.Structure):
_fields_ = [("tv_sec", ctypes.c_longlong),
("tv_usec", ctypes.c_longlong)]
class Stat(ctypes.Structure):
_fields_ = [("st_dev", ctypes.c_ulong),
("st_ino", ctypes.c_ulong),
("st_mode", ctypes.c_ulong),
("st_nlink", ctypes.c_ulong),
("st_uid", ctypes.c_ulong),
("st_gid", ctypes.c_ulong),
("st_rdev", ctypes.c_ulong),
("st_size", ctypes.c_ulonglong),
("st_blksize", ctypes.c_ulonglong),
("st_blocks", ctypes.c_ulonglong),
("st_atim", Timespec),
("st_mtim", Timespec),
("st_ctim", Timespec)]
Stat_p = ctypes.POINTER(Stat)
stat.argtypes = [ctypes.c_char_p, Stat_p]
path = "/tmp"
c_path = ctypes.c_char_p(path)
st = Stat()
rc = stat(c_path, ctypes.byref(st))
print rc
print st.st_dev
print st.st_ino
print st.st_mode
print st.st_nlink
print st.st_uid
print st.st_gid
print st.st_size
print st.st_atim
print st.st_mtim
-=-=-=-=-=-=-
This crashes immediately on one system, actually does work as expected
on another, but crashes before exiting. Clearly I must be doing
something wrong, but what?
On the system I have handy at the moment, it does not print any output, and
backtrace looks like this:
$ ./my_ctypes.py
*** Error in `/usr/bin/python': corrupted size vs. prev_size: 0x00000000027b8320 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f6444a907e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x7e9dc)[0x7f6444a979dc]
/lib/x86_64-linux-gnu/libc.so.6(+0x81cde)[0x7f6444a9acde]
/lib/x86_64-linux-gnu/libc.so.6(__libc_malloc+0x54)[0x7f6444a9d184]
/lib/x86_64-linux-gnu/libc.so.6(_IO_file_doallocate+0x55)[0x7f6444a861d5]
/lib/x86_64-linux-gnu/libc.so.6(_IO_doallocbuf+0x34)[0x7f6444a94594]
/lib/x86_64-linux-gnu/libc.so.6(_IO_file_overflow+0x1c8)[0x7f6444a938f8]
/lib/x86_64-linux-gnu/libc.so.6(_IO_file_xsputn+0xad)[0x7f6444a9228d]
/lib/x86_64-linux-gnu/libc.so.6(_IO_vfprintf+0xc90)[0x7f6444a66e00]
/lib/x86_64-linux-gnu/libc.so.6(__fprintf_chk+0xf9)[0x7f6444b2fb89]
/usr/bin/python[0x53290c]
/usr/bin/python[0x511c1f]
/usr/bin/python(PyFile_WriteObject+0x533)[0x5116d3]
/usr/bin/python(PyEval_EvalFrameEx+0x3a8f)[0x4c7a8f]
/usr/bin/python(PyEval_EvalCodeEx+0x255)[0x4c2765]
/usr/bin/python(PyEval_EvalCode+0x19)[0x4c2509]
/usr/bin/python[0x4f1def]
/usr/bin/python(PyRun_FileExFlags+0x82)[0x4ec652]
/usr/bin/python(PyRun_SimpleFileExFlags+0x191)[0x4eae31]
/usr/bin/python(Py_Main+0x68a)[0x49e14a]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7f6444a39830]
/usr/bin/python(_start+0x29)[0x49d9d9]
More information about the Python-list
mailing list