Python verwendet ctypes, um ein char * -Array zu übergeben und Ergebnisse zu füllen

8

Ich versuche ctypes zu verwenden, um ein char * -Array in Python zu erstellen, das an eine Bibliothek übergeben wird, um sie mit Strings zu füllen. Ich erwarte 4 Strings zurück mit nicht mehr als jeweils 7 Zeichen Länge.

Mein Py-Code sieht so aus

testlib.py

%Vor%

lib.cpp

%Vor%

Ich erhalte immer wieder Segmentierungsfehler, wenn ich versuche, diesen Code auszuführen. Ich habe einen Test von C erstellt, der perfekt funktioniert, aber in Python muss ich das Zeiger-Array falsch oder etwas einrichten. Es scheint, zum zweiten Knoten in der Schleife zu kommen und dann ein Problem zu haben, wie ich vom Ausspucken von Daten in die Befehlszeile gesehen habe. Jede Einsicht würde sehr geschätzt werden.

    
bitwit 22.05.2013, 19:09
quelle

3 Antworten

9

Der folgende Code funktioniert:

test.py:

%Vor%

test.c (kompiliert nach libtest.so mit gcc test.c -o libtest.so -shared -fPIC ):

%Vor%

Wie Aya sagte, solltest du sicherstellen, dass Platz für die abschließende Null ist. Aber ich denke, Ihr Hauptproblem war, dass der String-Puffer Müll gesammelt wurde oder etwas Ähnliches, da es keinen direkten Bezug mehr gab. Oder etwas anderes verursacht beim Erstellen der Zeichenfolgenpuffer Probleme, wenn für sie keine Referenzen gespeichert werden. Zum Beispiel ergibt dies viermal die gleiche Adresse anstelle von verschiedenen Adressen:

%Vor%     
Florian Rhiem 22.05.2013, 19:36
quelle
3

In dieser Zeile:

%Vor%

Sie erstellen einen einzelnen Puffer von 7 Bytes und versuchen dann, ihn zu verwenden, um 4 Zeichenzeiger zu halten (die wahrscheinlich jeweils 4 Bytes sind), und dann auch 4 8-Byte-Zeichenfolgen in zufällige Adressen zu kopieren zeigen auf. Sie müssen für jede Zeichenfolge einen Puffer reservieren und auch das Array von Zeigern zuweisen. Etwas wie das:

%Vor%     
Lee Daniel Crocker 22.05.2013 19:33
quelle
2

Ich kann den Code nicht (einfach) testen, aber basierend auf dem, was Sie gesagt haben, meine Vermutung wäre das Problem liegt in der Zeile ...

%Vor%

Laut den Python-Dokumenten für create_string_buffer() ...

  

init_or_size muss eine Ganzzahl sein, die die Größe des Arrays angibt,   oder eine Zeichenfolge, die zum Initialisieren der Array-Elemente verwendet wird.

     

Wenn eine Zeichenfolge als erstes Argument angegeben wird, wird der Puffer zu eins gemacht   Element größer als die Länge der Zeichenfolge, so dass das letzte Element in   Das Array ist ein NULL-Beendigungszeichen. Eine ganze Zahl kann als übergeben werden   zweites Argument, mit dem die Größe des Arrays angegeben werden kann, wenn der   Länge der Zeichenfolge sollte nicht verwendet werden.

... was impliziert, dass es ein char[7] erstellt, aber ein strcpy() versucht, das NULL -Terminator für eine Zeichenfolge zu kopieren. Wenn Ihre maximale Länge des "Knotennamens" also sieben Zeichen beträgt, benötigen Sie a char[8] , um die NULL zu behalten, obwohl du vielleicht mit memcpy(array[i], nodes[i], 7) anstelle von strcpy() durchkommst.

Wie auch immer, es ist wahrscheinlich am sichersten, stattdessen create_string_buffer(8) zu verwenden.

    
Aya 22.05.2013 19:25
quelle

Tags und Links