2010-08-16 17 views
17

मैं एक सी समारोह जो उम्मीद एक सूची \ 0 इनपुट के रूप में समाप्त तार:अजगर से करने के लिए स्ट्रिंग की एक सूची पासिंग/सी कार्य करने के लिए ctypes की उम्मीद कर चार **

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

अजगर से (ctypes के साथ) मैं

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

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

कैसे अजगर तरफ आंकड़ा संरचना का निर्माण करने पर कोई सुझाव: इस समारोह अजगर स्ट्रिंग की एक सूची के आधार पर कॉल करने के लिए चाहते हैं? निरीक्षण करें कि मैं गारंटी देता हूं कि सी फ़ंक्शन string_list में तारों की सामग्री को परिवर्तित नहीं करेगा।

सादर

Joakim

+0

सी फ़ंक्शन को यह कैसे पता चलता है कि यह 'const char *' के अनुक्रम के अंत तक पहुंच गया है? – habnabit

+0

ठीक है; सामान्य रूप से यह निश्चित रूप से नहीं जानता है। मेरा इरादा इसे एक पूर्ण के साथ समाप्त करना था, वैकल्पिक रूप से मैं लंबाई के साथ-साथ (char **) पॉइंटर में भी पास कर सकता हूं - मेरे पास सी पुस्तकालय पर पूर्ण नियंत्रण है। जोकिम –

+0

यदि यह नहीं पता है, तो यह बहुत बेकार है। आपको इसे किसी भी तरह बताने की ज़रूरत है, और हमें * बताएं ताकि हम आपको कोड दे सकें जो काम करता है। – habnabit

उत्तर

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

आपको बहुत बहुत धन्यवाद, वह आकर्षण की तरह काम किया। मैं भी इस तरह एक वैकल्पिक भिन्नता किया:

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

और जब तक मैं एक शून्य पाया तो सी-समारोह में मैं (चार **) सूची के माध्यम से दोहराया।

Joakim

1

मैं सिर्फ यह demo.i इंटरफ़ेस फ़ाइल में typemap

1.Write अनुकूलित typemap बड़ा घूँट का उपयोग कर सकते हैं।

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

2.generate विस्तार

$ 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 

अजगर में मॉड्यूल 3.import।

>>> from demo import yourfunction 
संबंधित मुद्दे