#c #python #boost-python
#c #python #boost-python
Вопрос:
Я хочу выделить буфер в C и предоставить его python в качестве объекта memoryview. Для этого я предоставляю эту функцию с помощью boost::python :
object* Allocator()
{
void* buff = my_alloc_function(char, size);
Py_buffer pybuffer;
int res = PyBuffer_FillInfo(amp;pybuffer, 0, buff, size, false, PyBUF_CONTIG);
if (res == -1)
return NULL;
handle<> obj_handle(borrowed(PyMemoryView_FromBuffer(amp;pybuffer)));
object obj = object(obj_handle);
return amp;obj;
}
Я также хочу иметь возможность предоставлять деструктор C , вызываемый python, как только счетчик ref объекта python становится равным нулю.
Мне удалось вызвать мой деструктор с помощью python и получить возвращаемый указатель с помощью Allocator() в качестве параметра моего деструктора.
Далее, текущая функция C , вызываемая python :
void Destructor()(object* pyMemoryView_object) const
{
Py_buffer* py_buffer = PyMemoryView_GET_BUFFER(pyMemoryView_object);
my_free_function(py_buffer->buf);
PyBuffer_Release(py_buffer);
}
Кажется, все идет хорошо, пока не вызван деструктор…
Проблема, с которой я сталкиваюсь, заключается в том, что Py_buffer py_buffer
имеет допустимый адрес, но содержит удаленные элементы (как показано как 0xcccccccccc в отладчике).
Мой первый вопрос :
Как вернуть допустимый объект Py_buffer в C из python, пока этот объект был создан с использованием handle<> и обернут в объект python ?
Мой второй вопрос будет :
Должен ли я вызывать PyBuffer_Release(), поскольку он может быть вызван python после вызова Destructor() ?
Спасибо за всю вашу помощь!
Ответ №1:
Мне удалось заставить его работать.
Вот код двух функций (без политики возврата при их предоставлении):
PyObject* Allocator()
{
void* buff = my_alloc_function(char, size);
Py_buffer pybuffer;
int res = PyBuffer_FillInfo(amp;pybuffer, 0, buff, size, false, PyBUF_CONTIG);
if (res == -1)
return NULL;
return PyMemoryView_FromBuffer(amp;pybuffer);
}
void Destructor()(object pyMemoryView_object) const
{
Py_buffer* py_buffer = PyMemoryView_GET_BUFFER(pyMemoryView_object.ptr());
my_free_function(py_buffer->buf);
PyBuffer_Release(py_buffer);
}
Важный момент, который я усвоил, заключается в том, что при возврате объекта в python используйте PyObject*
.
При получении объекта из python используйте object
.
Ответ №2:
Глядя на ваш пример, я буду удивлен, если возврат адреса объекта, выделенного в стеке, является приемлемым. Просто вернуть объект по значению?
Комментарии:
1. Я получаю те же результаты, если помещаю эти элементы в статическую область видимости.