2010-11-04 20 views
5

Estoy tratando de pasar una matriz de matrices de caracteres a una función C usando ctypes.Multi-dimensional char array (conjunto de cadenas) en 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); 

Desde la matriz que lo tiro todo se define estáticamente todos modos, acabo de cambiar la declaración de función y entrada de parámetros, así:

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); 

Ahora me encuentro con el problema de cómo definir este carácter multidimensional matriz en python. Yo había pensado que iría así:

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) 

Esto me da TypeError: incompatible types, c_char_Array_4 instance instead of c_char_p instance. Si lo cambio a:

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

Luego recibo fallas de segmentación. También esto se ve como el camino equivocado para construir la matriz 2d porque si imprimo de entrada veo None:

print input[0] 
print input[1] 

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

también me encuentro con el problema de la utilización de #DEFINE MY_ARRAY_X 2 y #DEFINE MY_ARRAY_Y 4 para mantener las dimensiones de la matriz directamente en mis archivos de C, pero no conozco una buena forma de obtener estas constantes de libhello.so para que python pueda referenciarlas cuando construya los tipos de datos.

+0

@ user17925 algún comentario acerca de éste? –

+0

@Purcaru se ve bien; ¡Trabajé tu construcción en mi código y funcionó! La documentación de python proporcionó esa función de ayuda create_string_buffer, así que supongo que estaba decidido a usarla. – user17925

Respuesta

9

usar algo como

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

Uso simple:

>>> 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

Gracias. ¡Esto es realmente genial! – Ajoy

Cuestiones relacionadas