Форум сайта python.su
Добрый день.
Господа специалисты, помогите пожалуйста вашему зеленому коллеге. Есть либа примерно следующего содержания:
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);
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
...
AttributeError: 'LP_shell' object has no attribute 'p'
...
Офлайн
Кхм. Второй вопрос снимается, я таки нашел затыку. LP_… оказывается означает long pointer to … ctypes не может самостоятельно определить является ли полученная ссылка на атомарное значение, либо на массив объектов. Чтобы расставить все по местам, вызов функции необходимо было сделать так:
...
s1 = ex_obj.Init()[0]
...
...
print s1.p.contents.x
...
Офлайн
Снова я. По сложившейся доброй традиции ответ на первый вопрос.
Прежде чем объявить указатель на функцию, необходимо выписать соответствующие прототипы.
Для примера из первого поста картина будет такая:
...
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),...]
Офлайн
За пост спасибо! Возникла такая же проблема.
Офлайн