Уведомления

Группа в Telegram: @pythonsu

#1 Апрель 28, 2009 16:04:14

Sansara
От:
Зарегистрирован: 2009-04-28
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

И вновь о ctypes

Добрый день.
Господа специалисты, помогите пожалуйста вашему зеленому коллеге. Есть либа примерно следующего содержания:

void Print(void);
void Add(int x,int y);

typedef struct point
{
int x;
int y;
} pnt;
struct shell
{
void (*Print)(void);
void (*Add)(int x,int y);
pnt *_point;
};

shell *Init(void);
Вопрос первый: Как правильно объявить указатели на функцию в составе полей?
Вопрос второй: Либа собирается под Linux. Дальше при попытке инициализировать структуру и обратиться ее членам возникает ошибка:
from ctypes import *

ex_obj = CDLL("libexample.so")

class my_point(Structure):
_fields_ = [("x",c_int),("y",c_int)]

class shell(Structure):
pass
shell._fields_ = [("p",POINTER(my_point)),...]

ex_obj.Init.restype = POINTER(shell)

s1 = ex_obj.Init()
print s1.p.x
В рамках Init атрибутам вложенной структуры присваиваются некоторые значения, однако при попытке обращения к атрибутам в python возникает исключение:
...
AttributeError: 'LP_shell' object has no attribute 'p'
...
с уважением Sansara.
ЗЫ. Маны читал, примеры рассматривал, все изложенные в доках примеры работают, бо являются достаточно тривиальными.



Офлайн

#2 Апрель 29, 2009 10:32:32

Sansara
От:
Зарегистрирован: 2009-04-28
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

И вновь о ctypes

Кхм. Второй вопрос снимается, я таки нашел затыку. LP_… оказывается означает long pointer to … ctypes не может самостоятельно определить является ли полученная ссылка на атомарное значение, либо на массив объектов. Чтобы расставить все по местам, вызов функции необходимо было сделать так:

     ...
s1 = ex_obj.Init()[0]
...
К атрибутам вложенной структуры необходимо было обратиться так:
     ...
print s1.p.contents.x
...
ЗЫ Вопрос первый все еще остается открытым



Офлайн

#3 Апрель 30, 2009 08:06:45

Sansara
От:
Зарегистрирован: 2009-04-28
Сообщения: 3
Репутация: +  0  -
Профиль   Отправить e-mail  

И вновь о ctypes

Снова я. По сложившейся доброй традиции ответ на первый вопрос.
Прежде чем объявить указатель на функцию, необходимо выписать соответствующие прототипы.
Для примера из первого поста картина будет такая:

     ...
PRNFUNC = CFUNCTYPE(c_void_p,c_void_p)
ADDFUNC = CFUNCTYPE(c_void_p,c_int,c_int)
...
class myclass(Structure):
pass
myclass._fields_ = [...,("Print",PRNFUNC),("Add",ADDFUNC),...]
Как-то так.
Глупо наверное отвечать на свои же посты, но может кому почитать будет полезно. Иногда прозрение наступает в момент, когда вопрос уже задан ))



Офлайн

#4 Сен. 13, 2009 16:27:20

lumen2000
От:
Зарегистрирован: 2008-02-19
Сообщения: 28
Репутация: +  0  -
Профиль   Отправить e-mail  

И вновь о ctypes

За пост спасибо! Возникла такая же проблема.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version