2010-11-04 3 views
5

Ich versuche, ein Array von Zeichen-Arrays zu einer C-Funktion mit Ctypes übergeben.Mehrdimensionale Char-Array (Array von Zeichenfolgen) in Python Ctypes

void cfunction(char ** strings) 
{ 
strings[1] = "bad"; //works not what I need. 
strings[1][2] = 'd'; //this will segfault. 
return; 
} 

char *input[] = {"foo","bar"}; 
cfunction(input); 

Da das Array, das ich um werfen statisch sowieso definiert ist, Ich habe gerade die Funktionsdeklaration und Eingabeparameter wie folgt:

void cfunction(char strings[2][4]) 
{ 
//strings[1] = "bad"; //not what I need. 
strings[1][2] = 'd'; //what I need and now it works. 
return; 
} 

char input[2][4] = {"foo","bar"}; 
cfunction(input); 

Jetzt laufe ich in das Problem, wie diese zu definieren, multidimensionales Zeichen Array in Python. Ich hatte gedacht, es gehen würde, wie so:

import os 
from ctypes import * 
libhello = cdll.LoadLibrary(os.getcwd() + '/libhello.so') 
input = (c_char_p * 2)() 
input[0] = create_string_buffer("foo") 
input[1] = create_string_buffer("bar") 
libhello.cfunction(input) 

Das gibt mir TypeError: incompatible types, c_char_Array_4 instance instead of c_char_p instance. Wenn ich es ändere zu:

for i in input: 
i = create_string_buffer("foo") 

Dann bekomme ich Segmentierungsfehler. Auch dies sieht aus wie der falsche Weg, um den 2D-Array zu bauen, weil, wenn ich Eingabe drucke ich sehe None:

print input[0] 
print input[1] 

# outputs None, None instead of "foo" and "foo" 

Ich laufe auch in die Frage der #DEFINE MY_ARRAY_X 2 und #DEFINE MY_ARRAY_Y 4 unter Verwendung der Array-Dimensionen gerade in meinen C-Dateien zu halten, aber ich kenne keinen guten Weg, um diese Konstanten aus libhello.so zu holen, damit Python sie referenzieren kann, wenn er die Datentypen erstellt.

+0

@ user17925 jedes Feedback auf diesem? –

+0

@Purcaru sieht gut aus; Ich habe deine Konstruktion in meinen Code eingearbeitet und es hat funktioniert! Die Python-Dokumentation lieferte die Helferfunktion create_string_buffer, also war ich gerade entschlossen, sie zu benutzen. – user17925

Antwort

9

Verwendung so etwas wie

input = ((c_char * 4) * 2)() 
input[0].value = "str" 
input[0][0] == "s" 
input[0][1] == "t" # and so on... 

Einfache Nutzung:

>>> a =((c_char * 4) * 2)() 
>>> a 
<__main__.c_char_Array_4_Array_2 object at 0x9348d1c> 
>>> a[0] 
<__main__.c_char_Array_4 object at 0x9348c8c> 
>>> a[0].raw 
'\x00\x00\x00\x00' 
>>> a[0].value 
'' 
>>> a[0].value = "str" 
>>> a[0] 
<__main__.c_char_Array_4 object at 0x9348c8c> 
>>> a[0].value 
'str' 
>>> a[0].raw 
'str\x00' 
>>> a[1].value 
'' 
>>> a[0][0] 
's' 
>>> a[0][0] = 'x' 
>>> a[0].value 
'xtr' 
+0

Danke. Das ist wirklich großartig! – Ajoy