gpt4 book ai didi

python - 使用 ctypes 处理 128 位整数

转载 作者:太空狗 更新时间:2023-10-29 21:11:13 24 4
gpt4 key购买 nike

使用 Python ctypes 支持 128 位整数(当前为 __uint128_t)的最佳方法是什么?

也许是两个 uint64_t 的用户定义结构,但这会在需要时产生对齐问题。

关于为什么 ctypes 没有扩展到支持 128 位整数有什么想法吗?

最佳答案

如果您真的想使用 128 位整数,那么您无需担心对齐问题。当前的体系结构和运行 Python 的机器均不支持 128 位 native 整数运算。因此,没有机器需要或受益于 128 位整数 16 字节对齐。只需使用该用户定义的结构就可以了。

如果您真正要求的是支持 128 位 vector 类型,那么您可能需要将它们对齐。也就是说,如果您在 Python 代码中创建它们并通过引用 C/C++ 代码传递它们,则需要对齐它们。您不能按值可靠地传递它们,没有办法让 ctypes 在堆栈上正确对齐它们(如果体系结构 ABI 需要的话)。从 C/C++ 传递到 Python 的向量可能已经正确对齐。因此,如果您可以安排它以便所有向量都在 C/C++ 代码中分配,您也应该可以使用用户定义的结构。

假设您确实需要在 Python 代码中创建对齐向量,那么我已经包含了用于对齐 ctypes 数组的代码。我还有一些代码可以将我未包含的其他 ctypes 类型与合理的代码大小对齐。对于大多数用途,数组应该足够了。这些对齐的阵列有几个限制。如果您将它们按值传递给 C/C++ 函数,或者如果您将它们作为成员包含在结构或联合中,它们将无法正确对齐。您可以使用 * 制作对齐数组的对齐数组运营商。

使用 aligned_array_type(<em>ctypes-type</em>, <em>length</em>, <em>alignment</em>)创建新的对齐数组类型。使用 aligned_type(<em>ctypes-type</em>, <em>alignment</em>)创建现有数组类型的对齐版本。

import ctypes

ArrayType = type(ctypes.Array)

class _aligned_array_type(ArrayType):
def __mul__(self, length):
return aligned_array_type(self._type_ * self._length_,
length, self._alignment_)

def __init__(self, name, bases, d):
self._alignment_ = max(getattr(self, "_alignment_", 1),
ctypes.alignment(self))

def _aligned__new__(cls):
a = cls._baseclass_.__new__(cls)
align = cls._alignment_
if ctypes.addressof(a) % align == 0:
return a
cls._baseclass_.__init__(a) # dunno if necessary
ctypes.resize(a, ctypes.sizeof(a) + align - 1)
addr = ctypes.addressof(a)
aligned = (addr + align - 1) // align * align
return cls.from_buffer(a, aligned - addr)

class aligned_base(object):
@classmethod
def from_address(cls, addr):
if addr % cls._alignment_ != 0:
raise ValueError, ("address must be %d byte aligned"
% cls._alignment_)
return cls._baseclass_.from_address(cls, addr)

@classmethod
def from_param(cls, addr):
raise ValueError, ("%s objects may not be passed by value"
% cls.__name__)

class aligned_array(ctypes.Array, aligned_base):
_baseclass_ = ctypes.Array
_type_ = ctypes.c_byte
_length_ = 1
__new__ = _aligned__new__

_aligned_type_cache = {}

def aligned_array_type(typ, length, alignment = None):
"""Create a ctypes array type with an alignment greater than natural"""

natural = ctypes.alignment(typ)
if alignment == None:
alignment = typ._alignment_
else:
alignment = max(alignment, getattr(typ, "_alignment_", 1))

if natural % alignment == 0:
return typ * length
eltsize = ctypes.sizeof(typ)
eltalign = getattr(typ, "_alignment_", 1)
if eltsize % eltalign != 0:
raise TypeError("type %s can't have element alignment %d"
" in an array" % (typ.__name__, alignment))
key = (_aligned_array_type, (typ, length), alignment)
ret = _aligned_type_cache.get(key)
if ret == None:
name = "%s_array_%d_aligned_%d" % (typ.__name__, length,
alignment)
d = {"_type_": typ,
"_length_": length,
"_alignment_": alignment}
ret = _aligned_array_type(name, (aligned_array,), d)
_aligned_type_cache[key] = ret
return ret

def aligned_type(typ, alignment):
"""Create a ctypes type with an alignment greater than natural"""

if ctypes.alignment(typ) % alignment == 0:
return typ
if issubclass(typ, ctypes.Array):
return aligned_array_type(typ._type_, typ._length_,
alignment)
else:
raise TypeError("unsupported type %s" % typ)

关于python - 使用 ctypes 处理 128 位整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19631698/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com