Почему двойной объект `ctypes.POINTER` работает для `char***`, а тройной `ctypes.POINTER` имел бы больше смысла?Python

Программы на Python
Ответить
Anonymous
 Почему двойной объект `ctypes.POINTER` работает для `char***`, а тройной `ctypes.POINTER` имел бы больше смысла?

Сообщение Anonymous »

У меня есть библиотека my_lib с функцией C, которая принимает параметр char***, указатель на массив char*, выделенный функцией. Вот минимальный воспроизводимый пример такой функции:
void getArrayOfStrings(char*** paramPtr)
{
(*paramPtr) = (char**) malloc(3*sizeof(char*));

(*paramPtr)[0] = (char*) malloc(strlen("Foo")+1);
strcpy((*paramPtr)[0], "Foo");

(*paramPtr)[1] = (char*) malloc(strlen("Bar")+1);
strcpy((*paramPtr)[1], "Bar");

(*paramPtr)[2] = 0;
}

Он устанавливает последний элемент массива в 0, чтобы вызывающий объект мог его идентифицировать (вместо того, чтобы указывать размер в качестве второго параметра). Обратите внимание, что для освобождения памяти предусмотрена отдельная функция.
Я запускаю ctypesgen, чтобы сгенерировать привязку Python к этой функции. Он генерирует этот код:
getArrayOfStrings = _lib.get("getArrayOfStrings", "cdecl")
getArrayOfStrings.argtypes = [POINTER(POINTER(POINTER(c_char)))]
getArrayOfStrings.restype = None

Эту сгенерированную привязку можно вызвать из приведенного ниже сценария Python:
import my_lib

import ctypes
names = ctypes.POINTER(ctypes.POINTER(ctypes.c_char))()

my_lib.getArrayOfStrings(names)

if names:
for name in names:
name_str = my_lib.String(name)
if name_str:
print("Got name: " + str(name_str))
else:
break

Он отлично работает и печатает «Foo\nBar\n»
Мне просто интересно, зачем использовать ctypes.POINTER(ctypes.POINTER( ctypes.c_char)), который я понимаю как «указатель на указатель на char», поэтому char** работает. Почему мне не следует использовать ctypes.POINTER(ctypes.POINTER(ctypes.POINTER(ctypes.c_char)))?
Я тестировал ctypes.POINTER(ctypes. POINTER(ctypes.POINTER(ctypes.c_char))), тот же код выдает ошибку:
my_lib.getArrayOfStrings(names)
OSError: exception: access violation writing 0x0000000000000000


Подробнее здесь: https://stackoverflow.com/questions/793 ... types-poin
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»