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