主要是您需要c_void_p作为void *,并且必须使用.contents取消引用返回.
这是一个工作示例(Windows)…
编辑:我添加了一个铸造空指针成员的示例.
test.h
#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);
test.c的
#define EXPORT
#include
#include
#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
",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返回的整数匹配.强制转换将该整数转换为POINTER(c_int),可以在其中提取内容.
5 00000216C0E2A5D0
t is <__main__.lp_mytype object at>
t.a is 5
t.b is 0x216c0e2a5d0
*b is c_long(123)