Hi, I have a segfault problem with ctypes. Script attached. I simply need to call `libgio.g_file_new_for_path` and then `libgio.g_file_get_uri` with its result. That result is a GFile*. Since I don't manipulate that GFile* I don't think I have to mess with argtypes & restype of the functions. I still tried ctypes.c_uint and ctypes.c_void_p. In all cases after a few iterations g_file_get_uri will segfault. This does not happen in the native version. You will find python & c script attached.
Here is the result of a typical run: $ LANG=C python2 ctypes_gio.py Step 0 getting g_file_ptr for /foo/bar getting uri_ptr with 8093280 free g_file_ptr getting uri free uri_ptr Step 1 getting g_file_ptr for /foo/bar getting uri_ptr with 8093344 free g_file_ptr getting uri free uri_ptr Step 2 getting g_file_ptr for /foo/bar getting uri_ptr with 8093824 free g_file_ptr getting uri free uri_ptr Step 3 getting g_file_ptr for /foo/bar getting uri_ptr with 8093440 free g_file_ptr getting uri free uri_ptr Step 4 getting g_file_ptr for /foo/bar getting uri_ptr with 8093472 free g_file_ptr getting uri free uri_ptr Step 5 getting g_file_ptr for /foo/bar getting uri_ptr with 8093856 free g_file_ptr getting uri free uri_ptr Step 6 getting g_file_ptr for /foo/bar getting uri_ptr with 140176928020160 free g_file_ptr Erreur de segmentation (core dumped) As you can see segfault happens as soon as the pointer position is outside [0, 2^31[. This is why I tried messing with argument/response types. What am I doing wrong? Any pointer (ahah) on how to solve my problem? The c code can be compiled that way: $ gcc $(pkg-config --cflags gio-2.0) segfault.c -o segfault $(pkg-config --libs gio-2.0) Thanks Bruno
import ctypes import ctypes.util class GioURI(object): """Use gio URI function g_file_get_uri. Paths must be utf-8 encoded. """ name = "GIO" def __init__(self): self.libgio = self.get_library() self.available = bool(self.libgio) def get_library(self): lib_name = ctypes.util.find_library("gio-2") try: return ctypes.cdll.LoadLibrary(lib_name) except OSError: return False def uri(self, path): print(b"getting g_file_ptr for %s" % path) self.libgio.g_file_new_for_path.restype = ctypes.c_void_p g_file_ptr = self.libgio.g_file_new_for_path(path) if not g_file_ptr: raise RuntimeError("No gfile pointer received for {0!r}".format( path)) try: print("getting uri_ptr with %s" % g_file_ptr) uri_ptr = self.libgio.g_file_get_uri.argtypes = [ctypes.c_void_p] uri_ptr = self.libgio.g_file_get_uri(g_file_ptr) except: print("got exception") raise finally: print("free g_file_ptr") self.libgio.g_object_unref(g_file_ptr) if not uri_ptr: print("free uri_ptr") self.libgio.g_free(uri_ptr) raise RuntimeError("No URI received from the gfile pointer for " "{0!r}".format(path)) try: print("getting uri") uri = ctypes.c_char_p(uri_ptr).value except: print("got exception") raise finally: print("free uri_ptr") self.libgio.g_free(uri_ptr) return uri def test(): gio = GioURI() if not gio.available: print("no gio") return for i in range(10): print("Step %s" % i) gio.uri(b"/foo/bar") if __name__ == '__main__': test()
#include <stdio.h> #include <gio/gio.h> int main() { int i; GFile* f; const char* path = "/foo/bar"; char* uri; for(i = 0; i < 100; i++) { f = g_file_new_for_path(path); printf("%i ", f); uri = g_file_get_uri(f); g_object_unref(f); printf("%s\n", uri); } return 0; }
-- https://mail.python.org/mailman/listinfo/python-list