2015-08-26 10 views
5

Chcę wyodrębnić adres liczby całkowitej, na którą wskazuje instancja ctypes.c_char_p.Jak uzyskać adres wskaźnika instancji ctypes.c_char_p

Na przykład w

>>> import ctypes 
>>> s = ctypes.c_char_p("hello") 
>>> s 
c_char_p(4333430692) 

wartość Chciałbym sprowadzić jest - adres ciąg hello\0 w pamięci:

(lldb) x 4333430692 
0x1024ae7a4: 68 65 6c 6c 6f 00 5f 70 00 00 00 00 05 00 00 00 hello._p........ 

Czytałem ctypes doktorzy, ale wydaje się, że nie ma na to żadnego sposobu. Najbliższe jest ctypes.addressof, ale to tylko daje mi lokalizację wskaźnika, oczywiście.

Powodem, dla którego tego chcę, jest to, że wywołuję niektóre funkcje C, które rzeczywiście oczekują adresów surowych zakodowanych jako liczby całkowite (których rozmiar jest równy naturalnej szerokości wskaźnika).

+0

Prototyp funkcji może używać 'intptr_t' lub' int64_t', ale to nie przeszkadza w używaniu 'c_char_p' w ctypes. Wskaźnik 'char *' jest przekazywany jako adres liczby całkowitej. – eryksun

+0

Oczywiście, ale przypadek użycia jest dla mnie nieco inny: jestem kodem JITing i muszę przekazać adres do pośredniej funkcji Pythona, która oczekuje liczb całkowitych, która następnie tworzy połączenie z funkcją C. Nie wspominałem o tym. – csl

Odpowiedz

6

Można po prostu rzucić go do c_void_p i uzyskać wartość:

>>> ctypes.cast(s, ctypes.c_void_p).value 
4333430692 
+0

Ah, próbowałem rzucić to na 'c_int64'! Dzięki! – csl

+4

Alternatywnie użyj protokołu buforowego: 'ctypes.c_void_p.from_buffer (s) .value'. Użycie 'from_buffer' jest około 3 razy szybsze, ponieważ' cast' jest zaimplementowany za pomocą wywołania FFI. Ale żeby ta różnica miała znaczenie, musielibyście to robić miliony razy w ciasnej pętli, która nie robi nic innego. – eryksun