Python中C _IOR函数的等价物是什么?

时间:2013-12-10 17:15:38

标签: python c ioctl

我最近在某些C代码上looking并“转换”到Python但却陷入了一个名为_IOR的特定函数。它在sys/ioctl.h中定义如下:

#define _IOC(inout,group,num,len) \
    (inout | ((len & IOCPARM_MASK) << 16) | ((group) << 8) | (num))
#define _IOR(g,n,t) _IOC(IOC_OUT,   (g), (n), sizeof(t))

我看到它以这些方式呼唤:

_IOR('t', 3, int)
_IOR('keys', 1, unsigned char *)

'钥匙'电话是我需要做的。看起来它正在对字符串进行逐位操作。

我设法找到了相应的Python代码,但它只适用于单个字符。

_IOC_NRBITS   =  8
_IOC_TYPEBITS =  8
_IOC_SIZEBITS = 14
_IOC_DIRBITS  =  2

_IOC_NRSHIFT = 0
_IOC_TYPESHIFT =(_IOC_NRSHIFT+_IOC_NRBITS)
_IOC_SIZESHIFT =(_IOC_TYPESHIFT+_IOC_TYPEBITS)
_IOC_DIRSHIFT  =(_IOC_SIZESHIFT+_IOC_SIZEBITS)

_IOC_NONE = 0
_IOC_WRITE = 1
_IOC_READ = 2
def _IOC(direction,type,nr,size):
    return (((direction)  << _IOC_DIRSHIFT) |
        ((type) << _IOC_TYPESHIFT) |
        ((nr)   << _IOC_NRSHIFT) |
        ((size) << _IOC_SIZESHIFT))
def _IOR(type, number, size):
    return _IOC(_IOC_READ, type, number, size)

这适用于单字符调用。

_IOR(ord('t'), 3, 1)

但我不知道第二次使用'keys'的等效电话。有没有办法在Python下面进行C调用?

_IOR('keys', 1, unsigned char *)

2 个答案:

答案 0 :(得分:0)

您在char *上运行时获得的数字不保证是任何特定数字。在为keys计算_IOR时,宏将字符串的地址视为整数。结果将根据keys在堆栈中的位置而变化。因此,Python中的这个功能实际上并不是一个很好的替代品。

来自docs for _IOR(g, n, t)

  


        指定此ioctl类型所属的组。这个论点必须         是一个非负8位数(即0-255范围内)。         如果是新的ioctl组,则可以将值零(0)传递给此参数         没有被定义。

该函数的预期用途是将一个字节作为第一个参数(通过字符或整数类型)。话虽这么说,'钥匙'可能被分配到一些随机组。我会选择一个你认为不会被采取的小组(或者在你的C代码中查找当前被分配到的小组并使用该号码)代替keys

或者,你总是可以只取输入字符串的第一个字符,并将其视为组ID。

def _IOR(group, number, size):
    if isinstance(group, basestring):
        group = ord(group[0]) if group else 0
    return _IOC(_IOC_READ, group, number, size)

然后_IOR('t', 3, 1)_IOR('keys', 1, 1)仍会运行,但组分配与C宏不同。但由于宏被误用于keys任务,我认为这不会是一个问题。

答案 1 :(得分:0)

'keys'是一个整数字符常量(包含四个字符),其值是实现定义的。您声明C代码_IOR('keys', 1, unsigned char *)返回的值是-444763391,它是一个4字节的十六进制数,0xE57D7301。由此我们可以得出结论,该实现计算来自'keys'的{​​{1}}的整数值0x6B657973。 'k'<<24|'e'<<16|'y'<<8|'s'值0xE57D7301来自表达式

_IOR

- 请注意,仅为TYPE(组)值保留了8个位,并且这种创造性使用32位值使TYPE溢出为SIZE和DIR位(与它们进行“或”运算)及其最高有效字节( 2<<30|4<<16|'keys'<<8|1 : : : : : : : 1 = num n : : 'keys' = group g : 4 = sizeof (unsigned char *) 2 = _IOC_READ )产生的结果甚至会移出'k'<<24值。

使用Python函数,您可以通过调用

来计算相同的值
int

(因为_IOR(ord('e')<<16|ord('y')<<8|ord('s'), 1, 4) 迷失了,我们可以直接放弃它。)