Как управлять строковой памятью с помощью Python ctypes - PullRequest
1 голос
/ 03 июня 2011

Мой код на Python вызывает функцию C в нативной библиотеке (также написанной мной). Функция принимает две строки в качестве аргументов и возвращает свой ответ в виде строки. Две строки аргументов, которые python передает в библиотеку C, читаются только библиотекой C, поэтому я не беспокоюсь об их управлении памятью. AFAIK, их память будет выделена python и будет освобождена, когда среда выполнения python покажется уместной.

Однако я понимаю, что память строки, которую возвращает библиотека C, должна управляться явно. Один способ, которым я могу это реализовать: функция C вызывает массив символов, заполняет его ответом и возвращает из функции. Код Python использует возвращаемую строку и должен вызвать libc free для этой строки или вызвать другую функцию из той же библиотеки C, которая позаботится об освобождении памяти.

Есть ли другой способ сделать это? Предлагает ли ctype какие-либо служебные функции, которые упрощают освобождение памяти структур данных, возвращаемых нативными библиотеками?

Ответы [ 2 ]

5 голосов
/ 03 июня 2011

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

В вашем случае, если вы заранее знаете верхний предел длины возвращаемой строки, используйте

buf = ctypes.create_string_buffer(upper_limt)

для выделения памяти в Python и передачи указателя на эту память в вашу функцию.

3 голосов
/ 03 июня 2011

Обычный способ сделать это - добавить дополнительный параметр буфера и параметр длины в функцию C. Если функция вызывается с размером буфера, который меньше требуемого размера, функция просто возвращает требуемый размер буфера и не выполняет никаких других действий, в противном случае данные копируются в буфер, а размер устанавливается равным фактическому размеру данные скопированы.

Это позволяет вам управлять буфером в Python за счет добавления 2 дополнительных параметров к вашей функции C.

...