2015-08-26 18 views
5

ctypes.c_char_p örneğinin işaret ettiği tamsayı adresini ayıklamak istiyorum.Bir ctypes.c_char_p örneğinin işaretçi adresi nasıl edinilir

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

ben almak istediğiniz değeri Örneğin

, olduğunu - bellekte dize hello\0 adresi: Ben ctypes okudum

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

docs, ama bunu yapmanın bir yolu yok gibi görünüyor. En yakın olan ctypes.addressof, ama bu sadece bana işaretçinin konumunu verir, elbette.

Bunun sebebi, tamsayı olarak kodlanmış (büyüklükleri yerel işaretçi genişliğine eşittir) işlenmemiş adreslerin beklendiği bazı C işlevlerini çağırmamın nedeni.

+0

fonksiyon prototipi 'intptr_t' veya' int64_t' kullanabilir, ancak bu ctypes içinde 'c_char_p' kullanmanızı engellemez. Bir char * 'işaretçisi bir tamsayı adresi olarak geçirilir. – eryksun

+0

Elbette, ama benim için kullanım durumu biraz farklı: Ben JITing kodu ve adresi bir C işlevi çağrısını birleştiren bir tamsayıları bekleyen bir ara Python işlevine iletmesi gerekiyor. Bundan bahsetmemiştim. – csl

cevap

6

Sadece c_void_p için döküm ve değer alabilir:

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

Ah, onu c_int64’e çevirmeyi denedim! Teşekkürler! – csl

+4

Alternatif olarak, arabellek protokolünü kullanın: 'ctypes.c_void_p.from_buffer (s) .value'. 'Cast' bir FFI çağrısı kullanılarak uygulandığından' from_buffer' kullanımı yaklaşık 3 kat daha hızlıdır. Fakat farkın farkına varmak için, milyonlarca kez, başka hiçbir şey yapmayan sıkı bir döngüde yapmalısınız. – eryksun