2010-11-04 43 views
5

J'essaie de transmettre un tableau de tableaux de caractères à une fonction C en utilisant ctypes.Tableau char multidimensionnel (tableau de chaînes) 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); 

Depuis le tableau que je jette autour est définie de façon statique de toute façon, Je viens de modifier la déclaration de fonction et paramètre d'entrée comme ceci:

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

Maintenant, je cours dans le problème de savoir comment définir cette caractère multidimensionnel tableau en python. Je pensais que ça irait comme ceci:

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) 

Cela me donne TypeError: incompatible types, c_char_Array_4 instance instead of c_char_p instance. Si je le change en:

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

Ensuite, je reçois des erreurs de segmentation. Aussi cela ressemble à la mauvaise façon de construire le tableau 2d parce que si j'imprime l'entrée je vois None:

print input[0] 
print input[1] 

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

Je lance également dans la question de l'utilisation #DEFINE MY_ARRAY_X 2 et #DEFINE MY_ARRAY_Y 4 pour garder les dimensions du tableau droit dans mes fichiers C, mais ne connaissez pas un bon moyen de sortir ces constantes de libhello.so afin que python puisse les référencer quand il construit les types de données.

+0

@ user17925 des commentaires sur celui-ci? –

+0

@Purcaru semble bon; J'ai travaillé votre construction dans mon code et ça a marché! La documentation python a fourni cette fonction d'assistance create_string_buffer, donc je suppose que j'étais juste déterminé à l'utiliser. – user17925

Répondre

9

Utilisez quelque chose comme

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

Utilisation 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

Merci. C'est vraiment génial! – Ajoy