Seite 1 von 2

Verfasst: Dienstag 2. Juni 2009, 12:07
von snafu
@ rayo:

Nein, immer noch das selbe:

Code: Alles auswählen

Traceback (most recent call last):
  File "./test.py", line 16, in <module>
    gtk_init(byref(argc), byref(argv))
ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: expected LP_LP_c_char_p instance instead of pointer to c_char_p_Array_1
Übrigens muss man natürlich oben aufpassen, dass man einmal die von Python ermittelte Länge der `sys.argv`-Liste nimmt, um die Größe des Arrays mittels Multiplikation festzulegen und erst danach das `c_int`-Objekt für die Übergabe als Funktionsparameter für C. ;)

Verfasst: Dienstag 2. Juni 2009, 12:37
von BlackJack
@snafu: Einen Typ Array gibt's indirekt über das Multiplizieren von Typen mit einer Zahl, aber Zeiger und Array sind ja in C fast das gleiche. Genau wie in C kannst Du mit `ctypes`-Zeigern auch Indexzugriffe machen. Bei `gtk_init()` sehe ich in der Signatur aber auch kein Array, sondern einen Zeiger auf einen Zeiger auf einen Zeiger auf `char`. Zeiger auf `char` gibt's schon als `c_char_p`, also müssen nur noch zwei der Sternchen durch `POINTER()` ersetzt werden.

Anscheinend ist `ctypes` da "typsicherer" als C, also bleibt nur `cast()`\en.

Verfasst: Dienstag 2. Juni 2009, 12:52
von snafu
Juchhu.

Code: Alles auswählen

#!/usr/bin/env python

from ctypes import byref, cast, c_char_p, CDLL, c_int, POINTER
from ctypes.util import find_library
import sys


def gtk_init(argv=sys.argv):
    assert isinstance(argv, list)
    args_no = len(argv)
    argc = c_int(args_no)
    argv = cast((c_char_p * args_no)(*argv), POINTER(c_char_p))

    gtk = CDLL(find_library('gtk-x11-2.0'))
    gtk_init = gtk.gtk_init
    gtk_init.argtypes = [POINTER(c_int), POINTER(POINTER(c_char_p))]
    return gtk_init(byref(argc), byref(argv)) == 1


if __name__ == '__main__':
    print gtk_init()
`ctypes` und ich werden, glaube ich, noch gute Freunde. :)

Verfasst: Mittwoch 3. Juni 2009, 09:18
von snafu
Hier mal ein Beispiel für ein `web_view` in einem Fenster. Mit dem Herumreichen von Variablen sozusagen innerhalb des C-Kontextes habe ich also kein Problem.

Schwierig wird allerdings das testweise Auslesen der URL aus meinem `network_request`. Signatur:

Code: Alles auswählen

const gchar *       webkit_network_request_get_uri      (WebKitNetworkRequest *request);
In meinem Ansatz sage ich einfach, dass die Rückgabe von Typ `c_char_p` ist, aber das reicht offenbar nicht. Ich bekomme nur irgendwelche komischen Zeichen zurück. :(

Verfasst: Mittwoch 3. Juni 2009, 09:40
von BlackJack
Was hättest Du denn jetzt da erwartet? Woher soll da auf magische Weise eine URI kommen?

Verfasst: Mittwoch 3. Juni 2009, 11:58
von snafu
Huch, danke. Die URL muss natürlich erst noch gesetzt werden. :oops:

Code: Alles auswählen

[...]
if __name__ == '__main__':
    init_gtk()
    request = webkit.webkit_network_request_new()
    
    url = 'http://www.google.de/'
    webkit.webkit_network_request_set_uri(request, url)
    
    get_uri = webkit.webkit_network_request_get_uri
    get_uri.restype = c_char_p
    print get_uri(request)