Как получить доступ к атрибутам структуры ctypes, как если бы они были ctypes, а не через данную оболочку? - PullRequest
1 голос
/ 23 июля 2011

Это противоречиво:

from ctypes import *

class S(Structure):
    _fields_ = [("x", POINTER(c_int)), ("y", c_int)]

o = S()
print o.x
print o.y

, что возвращает

<__main__.LP_c_int object at 0x10d3d08c0>
0

Так что в одном случае он возвращает тип ctypes, в другом случае он возвращает непосредственно значение.

У меня есть более общий код, в котором мне всегда нужно передавать экземпляр типа ctypes (который также доступен для записи, то есть запись в него будет означать изменение o в приведенном выше примере).Для o.x это нормально.Но не для o.y.

Как я могу получить c_int экземпляр o.y?

Ответы [ 2 ]

1 голос
/ 23 июля 2011

Из источника _ctypes кажется, что он не выполняет этого умного автоматического преобразования для простых экземпляров ctypes, когда они упакованы.

Итак, одно (безобразное) решение таково:

from ctypes import *

def WrapClass(c):
    class C(c): pass
    C.__name__ = "wrapped_" + c.__name__
    return C

class S(Structure):
    _fields_ = [("x", POINTER(c_int)), ("y", WrapClass(c_int))]

o = S()
print o.x
print o.y
print o.y.value
0 голосов
/ 15 октября 2015

Сначала я подумал, что это будет просто другой метод repr для "нормальных" типов, но после некоторого тестирования я думаю, что там происходит что-то определенно странное.Это действительно имеет значение, если что-то находится в структуре или нет.

from ctypes import *

class S(Structure):
    _fields_ = [("x", POINTER(c_int)), ("y", c_int), ("z", c_float)]

o = S()

x = POINTER(c_int)
y = c_int(1)
z = c_float(2.2)

print("In structure: x:{}, y:{}, z:{}".format(o.x, o.y, o.z))
print("Out of structure: x:{}, y:{}, z:{}".format(x, y, z))

В структуре: x: <<strong> main .LP_c_long объект в 0x000000000A090EC8>, y: 0, z: 0.0

Вне структуры: x :, y: c_long (1), z: c_float (2.200000047683716)

В частности, я считаю, что это следует считать ошибочным поведением:

o.x.contents = y #OK
o.x.contents = o.y #not OK!!

Traceback (последний вызов был последним): файл "", строка 1, в TypeError: ожидается c_long вместо int

...