Найти - Пользователи
Полная версия: И вновь о ctypes
Начало » Python для экспертов » И вновь о ctypes
1
Sansara
Добрый день.
Господа специалисты, помогите пожалуйста вашему зеленому коллеге. Есть либа примерно следующего содержания:
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.
ЗЫ. Маны читал, примеры рассматривал, все изложенные в доках примеры работают, бо являются достаточно тривиальными.
Sansara
Кхм. Второй вопрос снимается, я таки нашел затыку. LP_… оказывается означает long pointer to … ctypes не может самостоятельно определить является ли полученная ссылка на атомарное значение, либо на массив объектов. Чтобы расставить все по местам, вызов функции необходимо было сделать так:
     ...
s1 = ex_obj.Init()[0]
...
К атрибутам вложенной структуры необходимо было обратиться так:
     ...
print s1.p.contents.x
...
ЗЫ Вопрос первый все еще остается открытым
Sansara
Снова я. По сложившейся доброй традиции ответ на первый вопрос.
Прежде чем объявить указатель на функцию, необходимо выписать соответствующие прототипы.
Для примера из первого поста картина будет такая:
     ...
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),...]
Как-то так.
Глупо наверное отвечать на свои же посты, но может кому почитать будет полезно. Иногда прозрение наступает в момент, когда вопрос уже задан ))
lumen2000
За пост спасибо! Возникла такая же проблема.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB