[英]python ctypes unexpected behavior on windows
import ctypes
print(ctypes.c_int32)
在 linux(和 os x)上,此代码返回 <class 'ctypes.c_int32'> 在 windows 上返回 <class 'ctypes.c_long'>
为什么会发生这种情况以及如何解决这个问题? 我只想像在 Linux 上一样在 Windows 上运行软件。
更新
有自定义类
class ctype:
....
ctype.int32 = _make_ctype_from_ctypes(ctypes.c_int32)
....
使用此功能:
def _make_ctype_from_ctypes(ctypes_type):
ctypes_namespace = dict(ctypes_type.__dict__)
namespace = {
"__module__": _Numeric.__module__,
"_type_": ctypes_namespace["_type_"],
}
return type(
ctypes_type.__name__.replace("c_", ""),
tuple([_Numeric, *ctypes_type.__bases__]),
namespace,
)
错误发生在这里:
class _Numeric:
_type_: str
def __init__(self, value):
if isinstance(value, (bytearray, bytes)):
value = struct.unpack(self._type_, value)[0]
if isinstance(value, _Numeric):
value = value.value
if "int" in self.__class__.__name__:
value = int(value)
super().__init__(value) <-------------
堆栈跟踪
Traceback (most recent call last):
File "C:\Users\wotori\git\L2py\main.py", line 5, in <module>
print(clock.ticks)
File "C:\Users\wotori\git\L2py\game\game\models\world.py", line 40, in ticks
return ctype.int(int(time.time() - self.start_time) / self.MSEC_IN_TICK)
File "C:\Users\wotori\git\L2py\common\common\ctype.py", line 19, in __init__
super().__init__(value)
TypeError: 'float' object cannot be interpreted as an integer
我尝试将异常处理程序添加到问题发生的行,以便我们能够查看错误发生的确切数字,但这对我来说没有任何意义:
try:
super().__init__(value)
except Exception as e:
print("error", e, value)
错误输出:
error 'float' object cannot be interpreted as an integer 1639347702.44
error 'float' object cannot be interpreted as an integer 0.0
一点提醒,此代码适用于 linux 和 osx,但不适用于 Windows。
更新#2最小的例子。 此代码在 linux 上运行没有错误,但在 windows 上失败。 两台计算机上都安装了相同的 64 位 python。
if __name__ == '__main__':
from dataclasses import dataclass, field
import time
@dataclass(kw_only=True)
class Clock:
start_time: int = field(default=int(time.time()))
_is_night = False
TICKS_PER_SECOND = 10
MSEC_IN_TICK = 1000 / TICKS_PER_SECOND
@property
def is_night(self):
return self.hours < 6
@property
def hours(self):
return (self.get_time() / 60) % 24
@property
def ticks(self):
return ctype.int(int(time.time() - self.start_time) / self.MSEC_IN_TICK)
def get_time(self):
return ctype.int32(self.ticks / (self.TICKS_PER_SECOND * 10))
import struct
class _Numeric:
_type_: str
def __init__(self, value):
if isinstance(value, (bytearray, bytes)):
value = struct.unpack(self._type_, value)[0]
if isinstance(value, _Numeric):
value = value.value
if "int" in self.__class__.__name__:
value = int(value)
super().__init__(value)
def _make_ctype_from_ctypes(ctypes_type):
ctypes_namespace = dict(ctypes_type.__dict__)
namespace = {
"__module__": _Numeric.__module__,
"_type_": ctypes_namespace["_type_"],
}
return type(
ctypes_type.__name__.replace("c_", ""),
tuple([_Numeric, *ctypes_type.__bases__]),
namespace,
)
import ctypes
class ctype: # noqa
int = _make_ctype_from_ctypes(ctypes.c_int)
int32 = _make_ctype_from_ctypes(ctypes.c_int32)
clock = Clock()
print(clock.ticks)
堆栈跟踪:
Traceback (most recent call last):
File "C:\Users\wotori\git\L2py\main.py", line 69, in <module>
print(clock.ticks)
File "C:\Users\wotori\git\L2py\main.py", line 23, in ticks
return ctype.int(int(time.time() - self.start_time) / self.MSEC_IN_TICK)
File "C:\Users\wotori\git\L2py\main.py", line 42, in __init__
super().__init__(value)
TypeError: 'float' object cannot be interpreted as an integer
应该是:int(0)
没有什么可修复的。 在 Windows ctypes.c_int
和ctypes.c_int32
是ctypes.c_long
的别名,因为 C int
、 int32_t
和long
在 Windows 上都是相同的整数大小。
类ctypes。 c_int
表示 C 有符号 int 数据类型。 构造函数接受一个可选的整数初始化器; 没有进行溢出检查。 在sizeof(int) == sizeof(long)
的平台上,它是c_long
的别名。
...
类ctypes。 c_int32
表示 C 32 位有符号 int 数据类型。 通常是c_int
的别名。
编辑
根据代码更新,在 Windows 上ctype.int
和ctype.int32
都将是<class '__main__.long'>
。 在_Numeric.__init__()
中, self.__class__.__name__
将是'long'
。 换行:
if "int" in self.__class__.__name__:
如下所示,它会起作用,因为所有这些类型都需要value = int(value)
行将输入value
从float
更改为int
:
if self.__class__.__name__ in ('int', 'int32', 'long'):
您也可以考虑将这条线设为else:
如果三个 if 涵盖了所有基础。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.