ctypes:提取C库返回的结构的成员 [英] ctypes: extract members of structure returned by C library

查看:71
本文介绍了ctypes:提取C库返回的结构的成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用ctypes提取由C库初始化的结构(例如,请参见: https://tentacles666.wordpress.com/2012/01/21/python-ctypes-dereferencing-a-pointer-to-ac )。

I am trying to use ctypes to extract a structure initialized by a C library (see for example: https://tentacles666.wordpress.com/2012/01/21/python-ctypes-dereferencing-a-pointer-to-a-c).

原型是:

mytype * createMyType();

C中的结构为:

typedef struct
{
        int              a;
        void             *b;
}mytype;

在python(3)中是从哪个!我因此创建了一个ctypes结构:

from which in python(3)! I have created a ctypes structure thus:

class mytype(ctypes.Structure):
    _fields_ = [("a", ctypes.c_int),
               ("b", ctypes.POINTER(None))]

C调用为:

mytype*myinstance = createMyType()

Python调用如下:

The Python call is as follows:

import ctypes
f=mylib.createMyType
f.argtypes=()
f.restype=(ctypes.POINTER(mytype),)
x=f()

问题在于 x 似乎是整数;如何将其解释为指针,或者-根据需要-自己提取 x 的成员?

The problem is that x seems to be an integer; how do I interpret this as a pointer, or - as required - extract the members of x themselves?

如何我如何访问然后修改 xa xb

How do I access and then modify x.a and x.b?

[另请参见访问数据从Python中的C函数使用ctypes返回的结构中,导致不通]

[See also Accessing data from a structure returned by C function in Python using ctypes, which led nowhere]

推荐答案

主要是您需要 c_void_p 为void *,并且必须使用 .contents 取消引用返回。

Mainly you need c_void_p for the void* and must dereference the return with .contents.

这是一个有效的示例(Windows)...

Here's a working example (Windows)...

编辑:我添加了一个铸造void指针成员的示例。

Edit: I added an example of casting the void pointer member.

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 <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),可以在其中提取内容。

Output: Note that the void* b address output in the C code matches the integer returned by t.contents.b. The cast turns that integer into a POINTER(c_int) where the contents can be extracted.

5 00000216C0E2A5D0
t is <__main__.LP_mytype object at 0x00000216C30C4A48>
t.a is 5
t.b is 0x216c0e2a5d0
*b is c_long(123)

这篇关于ctypes:提取C库返回的结构的成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆