ctypes中的强类型转换可能吗? int - >例如,“指向struct的指针”

时间:2012-03-08 22:05:00

标签: python ctypes

我在回调中,允许我以int的形式访问传递给它的指针(即Python type()函数返回int)。

如果我想将其转换为struct的指针,我必须做什么,我知道它的布局并且可以定义为ctypes类。说我已经有了这个:

class data_t(Structure):
  _fields = [ ("foo", c_int), ("bar", c_wchar_p), ("baz", c_char_p) ]

x为其提供输出type(x)的变量int现在如何被转换为指向上述struct类型的指针?

要点:我对回调函数的声明或我要看到的参数声明没有影响,所以我需要一些方法来从Python int获取键入ctypes指针并从那里访问struct成员...

这是Python 2.6,但我认为大多数2.x至少会相似。我无法摆脱这个版本的要求,因为它嵌入到需要这个特定的 Python版本的产品中。

1 个答案:

答案 0 :(得分:4)

您可以使用ctypes.cast,或者只是声明回调以返回POINTER(data_t)。以下两个示例,并在Python 2.7和Python 3.2上进行测试:

测试DLL代码(Windows)

typedef struct data {
    int foo;
    wchar_t* bar;
    char* baz;
} data_t;

typedef void (*CALLBACK)(data_t* p);

CALLBACK g_callback = 0;

extern "C" __declspec(dllexport) void set_callback(CALLBACK f)
{
    g_callback = f;
}

extern "C" __declspec(dllexport) void call_callback()
{
    data_t data;
    data.foo = 123;
    data.bar = L"马克";
    data.baz = "Mark";
    g_callback(&data);
}

的Python

from ctypes import *

class data_t(Structure):
    _fields_ = [
        ("foo", c_int),
        ("bar", c_wchar_p),
        ("baz", c_char_p)]

dll = CDLL('test')

@CFUNCTYPE(None,c_int)
def callback(n):
    p = cast(n,POINTER(data_t)).contents
    print(p.foo,p.bar,p.baz)

@CFUNCTYPE(None,POINTER(data_t))
def callback2(n):
    p = n.contents
    print(p.foo,p.bar,p.baz)

dll.set_callback(callback)
dll.call_callback()

dll.set_callback(callback2)
dll.call_callback()

输出

123 马克 b'Mark'
123 马克 b'Mark'