我正在尝试使用IronPython 2.7.9中的ctypes创建一个位域类。我正在尝试示例in this answer。但是在访问联盟成员时,它在行SystemError: Object reference not set to an instance of an object
处失败flags.asbyte = 0xc
。
我还尝试通过添加CPython 2.7.8路径指向建议的in this message指向CPython stdlib,但这也不起作用。
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)
An example of ctypes on IronPython?可能很有趣,但是公认的答案并不能证明例子。
编辑:我进一步研究了一下,此代码(受from this unit test启发)无效:
from ctypes import *
class ANON(Union):
_fields_ = [("a", c_int),
("b", c_int)]
a = ANON()
a.a = 5
这段代码(from this unit test)起作用:
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的局限性
谢谢!
答案 0 :(得分:1)
您应该升级到IronPython的最新版本,因为上周发布了2.7.9。
答案 1 :(得分:0)
此问题被视为IronPython 2.7.9 ctypes.Union access fails with "SystemError: Object reference not set to an instance of an object."上的错误。
就目前而言,我想出了一个对我有用的非常丑陋的解决方案:
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),
]