LINUX.ORG.RU

Python FFI


0

1

Здравствуйте, возникла проблема с python ffi

Есть простая динамическая библиотека на C

#include <stdio.h>
#include <stdlib.h>

struct Data {
    int m;
};

void print_data(void* data)
{
    struct Data* d = data;
    printf("%x\n", d);
    printf("%d\n", d->m); // (1)
}

void* create_data(void)
{
    struct Data* d = malloc(sizeof(struct Data));
    d->m = 54; 
    print_data(d);
    return d;
}

И есть код на Python, который должен её вызывать

import ctypes

lib = ctypes.cdll.LoadLibrary("./libdata.so")
data = lib.create_data()
lib.print_data(data)

Вывод программы такой:

$ python test.py 
17407210
54
17407210
Ошибка сегментирования (core dumped)
gdb показывает, что сегфолт происходит на строке (1)

Правильно ли вообще я вызываю функции из библиотеки, и почему возникает ошибка?

Сама проблема возникла в питоновской программе Brainworkshop. Раньше она работала, а теперь вылетает в сегфолт в библиотеке libgdk_pixbuf, а вызывает нативные функции библиотека pyglets. Такое чувство, что в Питоне что-то поломали.

Такой пример на pyglets также сегфолтится:

import pyglet
pyglet.image.load("image.png")

Во внутренностях pyglets'а работа с .so-библиотеками реализована так же как у меня выше. Я просто воспроизвел это в сильно упрощенном виде, и получил тот же результат (сегфолт).

stack_protector
() автор топика
Ответ на: комментарий от stack_protector

Для начала, версию питона и дистрибутив в студию

17407210

54


17407210



print_data показала, что значение указателя перед сегфолтом такое же как и в удачном случае, это если у тебя 32-битная система. Для вывода значения указателей используй не %x, а %p

Такое чувство, что в Питоне что-то поломали.


или память битая, или карма. На питоне 3.2.2 сегфолт не воспроизводится

anonymous
()

Попробуй назначить функциям правильные прототипы:

create_data = lib.create_data
create_data.restype = ctypes.c_void_p

print_data = lib.print_data
create_data.argtypes = (ctypes.c_void_p, )
tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

>Для вывода значения указателей используй не %x, а %p

Точно, питон обрезает указатель до 32-битного.

Попробуй назначить функциям правильные прототипы:

Спасибо, так работает. Значит нужно писать багрепорт разработчиками pyglet'а. Они не присваивают argtypes

stack_protector
() автор топика

Оказалось что brainworkshop перестал работать потому, что я установил BSD'шный jemalloc, а он выделяет память за пределами 4х гигабайт. Потому почти никто и не сталкивается с проблемой — все используют дефолтный ptmalloc, который выделяет память так, что отрезание старших 32х бит от указателя его не изменяет.

Не в тему, но уменьшения потребления памяти jemalloc не дал, наоборот — памяти стало съедаться раза в полтора больше.

stack_protector
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.