Сбой объединения ctypes IronPyton с «SystemError: Ссылка на объект не установлена ​​для экземпляра объекта». - PullRequest
0 голосов
/ 16 октября 2018

Я пытаюсь создать класс битового поля, используя ctypes в IronPython 2.7.9.Я пытаюсь пример в этом ответе .но он не работает с SystemError: Object reference not set to an instance of an object в строке flags.asbyte = 0xc при доступе к члену Union.

Я также попытался указать на CPython stdlib, как предлагалось в этом сообщении , добавивПуть к CPython 2.7.8, но это тоже не сработало.

import sys

sys.path.append("C:/Python27/DLLs")

import ctypes
c_uint8 = ctypes.c_uint8

class Flags_bits(ctypes.LittleEndianStructure):
    _fields_ = [
            ("logout", c_uint8, 1),
            ("userswitch", c_uint8, 1),
            ("suspend", c_uint8, 1),
            ("idle", c_uint8, 1),
        ]

class Flags(ctypes.Union):
    _fields_ = [("b", Flags_bits),
                ("asbyte", c_uint8)]

flags = Flags()
flags.asbyte = 0xc

print(flags.b.idle)
print(flags.b.suspend)
print(flags.b.userswitch)
print(flags.b.logout)

Пример ctypes на IronPython? может быть интересным, но принятый ответ не является примером.

РЕДАКТИРОВАТЬ: Я копнул немного дальше, и этот код (вдохновленный из этого модульного теста ) не работает:

from ctypes import *

class ANON(Union):
    _fields_ = [("a", c_int),
                ("b", c_int)]

a = ANON()
a.a = 5

Хотя этот кусок кода ( из этого модульного теста ) работает:

from ctypes import *

class X(Structure):
    _fields_ = [("a", c_longlong, 1),
                ("b", c_longlong, 62),
                ("c", c_longlong, 1)]

x = X()
x.a, x.b, x.c = -1, 7, -1

Так что похоже на ограничение IronPython

Спасибо!

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

Эта проблема считалась ошибкой в ​​IronPython 2.7.9 ctypes.Union. Сбой при доступе: «SystemError: для ссылки на объект не задан экземпляр объекта.» .

ПокаЯ придумал это очень уродливое решение, которое работает для меня:

class __BleCharacteristicFlags(ctypes.LittleEndianStructure):
    """Creates a class to generically represent bitfields.

    Note:
        This ONLY supports ctypes.LittleEndianStructure.
        Unfortunately IronPython 2.7.9 does not supports ctypes.Union. We need this workaround
        code to create an illusion of an union.
    """
    @property
    def as_byte(self):
        """Returns an integer that represents the current set flags
        """
        val = 0
        for i, field in enumerate(self._fields_):
            if getattr(self, field[0]) == 1:
                val += (0x01<<i)
        return val

    @as_byte.setter
    def as_byte(self, hex_val):
        """Writes the flags with a single bitfield.
        """
        for i, field in enumerate(self._fields_):
            if( (hex_val&(0x01<<i)) != 0 ):
                setattr(self, field[0], 1)
            else:
                setattr(self, field[0], 0)

    def __str__(self):
        """Returns a string that represents the current object.
        """
        s = ""
        for i, field in enumerate(self._fields_):
            if getattr(self, field[0]) == 1:
                if s != "":
                    s += ", "
                s += field[0]
        return s

class BleCharacteristicPermissions(__BleCharacteristicFlags):
    """Creates a clas to represent the permissions of a GATT characteristic.

    Note:
        The flags values are:
            Readable = 0x01,
            Writeable = 0x02,
            ReadEncryptionRequired = 0x04,
            WriteEncryptionRequired = 0x08,

    Attributes:
        readable (int): Readable permission flag. If set the characteristic can be read.
        writeable (int): Writeable permission flag. If set the characteristic can be written.
        read_encryption_required (int): Read encryption required permission flag.  If set the
            characteristic can only be read if encryption is enabled.
        write_encryption_required (int): Write encryption required permission flag.  If set the
            characteristic can only be written if encryption is enabled.
        as_byte (int): The flags bit values read as an integer.
    """
    _fields_ = [
            ("readable", ctypes.c_uint8, 1),
            ("writeable", ctypes.c_uint8, 1),
            ("read_encryption_required", ctypes.c_uint8, 1),
            ("write_encryption_required", ctypes.c_uint8, 1),
        ]
0 голосов
/ 16 октября 2018

Вам следует перейти на последнюю версию IronPython, поскольку на прошлой неделе был выпущен 2.7.9.

http://ironpython.net/

...