2016-08-30 4 views
0

Ich habe eine schriftliche eine DLL, in dem ich einen der Wege bekommen:Wie kann ich mit Ctypes auf den Zeichenzeiger zugreifen?

//demo.h 
__declspec(dllexport) void pathinfo(char * path); 

Etwas im Code getan wird, diesen Weg zu bekommen. wie gezeigt Und nun wird der Python-Skript, das ich geschrieben habe, von der DLL diesen Weg abrufen:

//demo.py 
import sys 
import ctypes 
from ctypes import * 
class demo(object): 
    def __init__(self): 
    self.demoDLL=CDLL("demo.dll") 

    def pathinfo(self): 
    path=c_char() 
    self.demoDLL.pathinfo.argtypes(POINTER(c_char)) 
    self.demoDLL.pathinfo.result=None 
    self.demoDLL.pathinfo(byref(path)) 
    return path.value 

if __name__=='__main__': 
    abc=demo() 
    path_info=abc.pathinfo() 
    print "information of the path:",path_info 

Aber der Wert, ich bin in der Lage zu sehen, ist nur das erste Zeichen des Weges statt dem ganze Saite.

Kann mir jemand bei diesem Problem helfen?

Antwort

1

Der Grund, warum Sie nur das erste Zeichen zu sehen ist, dass c_char() durch den Aufruf Sie einen einzelnen char Wert zu schaffen, dass Python wie ein str (Python 2) Objekt oder bytes (Python 3) Objekt der Länge 1. Sie sind behandelt wahrscheinlich Glück, dass Sie keinen Segmentierungsfehler bekommen. Durch das Schreiben von mehr als 1 Byte oder einer NULL-terminierten Zeichenfolge der Länge> 0 (z. B. mit strcpy) in dem C-Code erzeugen Sie tatsächlich einen unerkannten Pufferüberlauf. ctypes weiß nicht, wie viele Bytes Sie am Speicher des Zeigers geschrieben haben. path.value ist immer noch ein str/bytes der Länge 1.

Es wäre besser, die C pathinfo Funktion in some zu ändern wie

size_t pathinfo(char* path, size_t bsize); 

Verwenden ctypes.create_string_buffer() Speicher in Ihrem Python-Code zuzuweisen und pathinfo Rückkehr die Länge lassen des Ergebnisses. Natürlich müssen Sie prüfen, ob char* path groß genug ist mit bsize in Ihrem C-Code.

Der Python-Code würde wie folgt aussehen:

buf = ctypes.create_string_buffer(256) 
result_len = pathinfo(buf, len(buf)) 
if result_len == len(buf): 
    # buffer may have been too short, 
    # try again with larger buffer 
    ... 
restlt_str = buf[0:result_len].decode('utf-8') # or another encoding 

Auch bewusst sein, von NULL-Terminierung in der C-Domäne, Kodierungen Zeichen, wenn Python Strings char* Umwandlung und zurück, die Änderungen in Bezug auf str/bytes in ctypes in Bezug auf Python 2 und Python 3.

0

habe es nicht getan, aber haben folgendes getan:

Um ein Array von ints, zum Beispiel passieren, verwenden:

Erstellen Sie eine Art von, sagen wir, 20 ints:

Ints20 = c_int * 20 

erstellen Sie eine Instanz:

data = Ints20() 

Und dann können Siepassieren. Extrahieren Sie die Zahlen aus data durch die list Funktion:

values = list(data) 

kann also sein, das Sie das gleiche mit Zeichen tun können:

Chars20 = c_char * 20 
path = Chars20() 

und dann:

self.demoDLL.pathinfo(path) 

Im Fall von c_char Array gibt es keine Notwendigkeit, die list Funktion zu verwenden, aber das funktioniert:

return path.value 
+0

Dies hat nicht funktioniert .. – user6730734

Verwandte Themen