2013-10-02 5 views

ответ

3

Как я боролся с этой проблемой в течение некоторого времени, я решил написать небольшой HowTo, чтобы другие люди могли извлечь выгоду.

Имея это C кусок кода:

void passPointerArray(int size, char **stringArray) { 
    for (int counter=0; counter < size; counter++) { 
    printf("String number %d is : %s\n", counter, stringArray[counter]); 
    } 
} 

Мы хотим, чтобы вызвать его из питона с помощью ctypes (подробнее о ctypes можно найти в предыдущем посте), поэтому напишем следующий код:

def pass_pointer_array(): 
    string_set = [ 
    "Hello", 
    "Bye Bye", 
    "How do you do" 
    ] 

    string_length = len(string_set) 

    select_type = (c_char_p * string_length) 
    select = select_type() 

    for key, item in enumerate(string_set): 
    select[key] = item 

    library.passPointerArray.argtypes = [c_int, select_type] 
    library.passPointerArray(string_length, select) 

Теперь, когда я прочитал это, кажется, очень простой, но я наслаждался много найти правильный тип, чтобы перейти к ctypes, чтобы избежать ошибки сегментации ...

+0

Если функция C изменяет строки , создайте массивы 'c_char' с помощью' create_string_buffer', например. 'select = (POINTER (c_char) * len (string_set)) (* map (create_string_buffer, string_set))'. – eryksun

+0

И какой тип arg следует использовать? –

+0

Если безопасность типа не вызывает беспокойства, вы можете просто использовать 'c_void_p'. Это примет любой тип указателя. Вы также можете использовать 'POINTER (POINTER (c_char))'. Тем не менее, система типа ctypes неумолима, поэтому, если вы смешиваете массивы 'c_char_p', вам придется« бросать »сначала, чтобы не дать ему ныть. – eryksun

Смежные вопросы