2016-07-13 3 views
1

Я пытаюсь использовать Cython, чтобы написать обертку вокруг библиотеки C++. Однако сейчас я сталкиваюсь с проблемой, так как одна из функций библиотеки принимает параметр const char**. По-видимому, C++ не может сделать это преобразование (Why am I getting an error converting a ‘float**’ to ‘const float**’?), что оставляет меня в дилемме, поскольку я передаю список строк, назовем это x в функцию, и я пытаюсь сгенерировать соответствующий объект char ** , давайте назовем его a, используя таНос и для цикла:Cython как преобразовать char ** в const char **?

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

есть обходной путь здесь? Единственное, о чем я могу думать, это использовать const_cast, и я не могу найти никаких подробностей о том, реализовано ли в Cython ....

ответ

2

Следующий код компилируется в cPython V20.0. Решает ли ваша проблема?

# 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

Он сделал, спасибо! – Alex

+0

Это работает до тех пор, пока список 'x' где-то упоминается. После этого массив указывает на ячейки памяти, которые были освобождены и, возможно, повторно использованы. Также изменения в содержимом 'x' могут вызвать проблемы. –

0

Существует этот старый answer но я бы реализовать to_cstring_array немного по-другому (использование strdup, не 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