Как я боролся с этой проблемой в течение некоторого времени, я решил написать небольшой 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, чтобы избежать ошибки сегментации ...
Если функция C изменяет строки , создайте массивы 'c_char' с помощью' create_string_buffer', например. 'select = (POINTER (c_char) * len (string_set)) (* map (create_string_buffer, string_set))'. – eryksun
И какой тип arg следует использовать? –
Если безопасность типа не вызывает беспокойства, вы можете просто использовать 'c_void_p'. Это примет любой тип указателя. Вы также можете использовать 'POINTER (POINTER (c_char))'. Тем не менее, система типа ctypes неумолима, поэтому, если вы смешиваете массивы 'c_char_p', вам придется« бросать »сначала, чтобы не дать ему ныть. – eryksun