ctypes:提取C库返回的结构的成员
我正在尝试使用ctypes提取由C库初始化的结构(请参阅例如:https :
//tentacles666.wordpress.com/2012/01/21/python-ctypes-dereferencing-a-
pointer-to-ac) 。
“原型”是:
mytype * createMyType();
C中的结构为:
typedef struct
{
int a;
void *b;
}mytype;
从中的python(3)!我因此创建了一个ctypes结构:
class mytype(ctypes.Structure):
_fields_ = [("a", ctypes.c_int),
("b", ctypes.POINTER(None))]
C调用是:
mytype*myinstance = createMyType()
Python调用如下:
import ctypes
f=mylib.createMyType
f.argtypes=()
f.restype=(ctypes.POINTER(mytype),)
x=f()
问题在于,这x
似乎是一个整数。如何将其解释为指针,或者-根据需要-提取x
自身的成员?
如何访问,然后修改x.a
和x.b
?
[另请参见使用ctypes从Python中C函数返回的结构访问数据,这无处可寻]
-
主要是您需要
c_void_p
void *,并且必须使用取消引用返回值.contents
。这是一个工作示例(Windows)…
编辑 :我添加了一个铸造空指针成员的示例。
测试
#ifdef EXPORT #define API __declspec(dllexport) #else #define API __declspec(dllimport) #endif typedef struct { int a; void* b; } mytype; API mytype* createMyType(); API void destroyMyType(mytype* p);
测试
#define EXPORT #include <stdlib.h> #include <stdio.h> #include "test.h" API mytype* createMyType() { int* tmp; mytype* p = malloc(sizeof(mytype)); p->a = 5; tmp = malloc(sizeof(int)); *tmp = 123; p->b = tmp; printf("%d %p\n",p->a,p->b); return p; } API void destroyMyType(mytype* p) { free(p->b); free(p); }
test.py
from ctypes import * class mytype(Structure): _fields_ = [('a',c_int), ('b',c_void_p)] test = CDLL('test') createMyType = test.createMyType createMyType.argtypes = None createMyType.restype = POINTER(mytype) destroyMyType = test.destroyMyType destroyMyType.argtypes = POINTER(mytype), destroyMyType.restype = None t = createMyType() print('t is',t) print('t.a is',t.contents.a) print('t.b is',hex(t.contents.b)) b = cast(t.contents.b,POINTER(c_int)) print('*b is',b.contents) destroyMyType(t)
输出 :请注意,C代码中输出的void * b地址与所返回的整数匹配
t.contents.b
。将该cast
整数转换为POINTER(c_int)
可以提取内容的位置。5 00000216C0E2A5D0 t is <__main__.LP_mytype object at 0x00000216C30C4A48> t.a is 5 t.b is 0x216c0e2a5d0 *b is c_long(123)