2010-08-16 20 views
17

ben bir liste \ 0 girdi olarak dizeleri sona beklediği bir Cı fonksiyonu:/C işlev ctypes bekliyor char **

piton kaynaktan (ctypes ile)
void external_C(int length , const char ** string_list) { 
    // Inspect the content of string_list - but not modify it. 
} 

I piton tarafında veri tipleri de kurmak için nasıl

def call_c(string_list): 
    lib.external_C(??) 

call_c(["String1" , "String2" , "The last string"]) 

Herhangi bir ipucu: piton dizeleri listesine dayanarak bu işlevi çağırmak istiyorum? C işlevinin string_list içindeki dizelerin içeriğini değiştirmeyeceğini garanti ediyorum.

Selamlar

joakim

+0

C işlevi, const const * dizisinin sonuna ulaştığını nasıl biliyor? – habnabit

+0

Eh; Genelde elbette bilmiyor. Niyetimi bir NULL ile sona erdirmek istedim, alternatif olarak (char **) işaretçisinin yanı sıra bir uzunlukta da geçebilirim - söz konusu C kütüphanesi üzerinde tam kontrole sahibim. Joakim –

+0

Bilmiyorsa, bu oldukça işe yaramaz. Bunu bir şekilde anlatmalısın, ve söyle * bize * böylece size işleyen bir kod verebiliriz. – habnabit

cevap

20
def call_c(L): 
    arr = (ctypes.c_char_p * len(L))() 
    arr[:] = L 
    lib.external_C(len(L), arr) 
5

Çok teşekkür ederim; cazibe gibi çalıştı. Ayrıca bu gibi alternatif bir varyasyon yaptı:

def call_c(L): 
    arr = (ctypes.c_char_p * (len(L) + 1)))() 
    arr[:-1] = L 
    arr[ len(L) ] = None 
    lib.external_C(arr) 

ve bir NULL bulana kadar C grubu işlev I (char **) liste boyunca tekrarlanır.

Joakim

1

Sadece demo.i arayüz dosyasında

1.write özelleştirilmiş türeşlem türeşlem SWIG kullanarak yapın.

%module demo 

/* tell SWIG to treat char ** as a list of strings */ 
%typemap(in) char ** { 
    // check if is a list 
    if(PyList_Check($input)) 
    { 
     int size = PyList_Size($input); 
     int i = 0; 
     $1 = (char **)malloc((size + 1)*sizeof(char *)); 
     for(i = 0; i < size; i++) 
     { 
      PyObject * o = PyList_GetItem($input, i); 
      if(PyString_Check(o)) 
       $1[i] = PyString_AsString(o); 
      else 
      { 
       PyErr_SetString(PyExc_TypeError, "list must contain strings"); 
       free($1); 
       return NULL; 
      } 
     } 
    } 
    else 
    { 
     PyErr_SetString(PyExc_TypeError, "not a list"); 
     return NULL; 
    } 
} 

// clean up the char ** array 
%typemap(freearg) char ** { 
    free((char *) $1); 
} 

python modülü 3.Import 2.generate uzatma

$ swig -python demo.i // generate wrap code 
$ gcc -c -fpic demo.c demo_wrap.c 
$ gcc -shared demo.o demo_wrap.o -o _demo.so 

.

>>> from demo import yourfunction