2016-07-13 3 views
1

Ich versuche Cython zu verwenden, um einen Wrapper um eine C++ - Bibliothek zu schreiben. Ich stoße jetzt auf ein Problem, da eine der Funktionen in der Bibliothek den Parameter const char** annimmt. Anscheinend kann C++ diese Konvertierung nicht machen, (Why am I getting an error converting a ‘float**’ to ‘const float**’?) was mich in ein Dilemma versetzt, da ich eine Liste von Strings übergebe, nennen wir sie x in der Funktion, und ich versuche das entsprechende char ** -Objekt zu generieren lassen sie uns es a nennen, malloc und einer for-Schleife:Cython wie man char ** in const char ** umwandelt?

def f(x): 
cdef char** a = <char**> malloc(len(x) * sizeof(char*)) 
for index, item in enumerate(x): 
    a[index] = item 
...... 

gibt es hier eine Abhilfe? Das einzige, was ich mir vorstellen kann, ist die Verwendung const_cast, und ich kann keine Details finden, ob das in Cython implementiert ist oder nicht ....

Antwort

2

Der folgende Code kompiliert in cPython V20.0. Löst das dein Problem?

# distutils: language = c++ 

from libc.stdlib cimport malloc 

def f(x): 
    cdef const char** a = <const char**> malloc(len(x) * sizeof(char*)) 
    for index, item in x: 
     a[index] = item 
+1

Es tat dank implementieren! – Alex

+0

Dies funktioniert so lange wie auf die Liste 'x' verwiesen wird. Danach zeigt das Array auf Speicherorte, die freigegeben und möglicherweise wiederverwendet wurden. Auch Änderungen im Inhalt von 'x' könnten Probleme verursachen. –

0

Es ist diese alte answer aber ich würde to_cstring_array wenig anders (Verwendung von strdup, kein PyString_AsString)

from libc.stdlib cimport malloc, free 
from libc.string cimport strdup 

cdef char ** to_cstring_array(list strings): 
    cdef const char * s 
    cdef size_t l = len(strings) 

    cdef char ** ret = <char **>malloc(l* sizeof(char *)) 
    # for NULL terminated array 
    # cdef char ** ret = <char **>malloc((l + 1) * sizeof(char *)) 
    # ret[l] = NULL 

    for i in range(l): 
     s = strings[i] 
     ret[i] = strdup(s) 
    return ret