Python 中的 C _IOR 函数的等价物是啥?
Posted
技术标签:
【中文标题】Python 中的 C _IOR 函数的等价物是啥?【英文标题】:What is the equivalent of the C _IOR function in Python?Python 中的 C _IOR 函数的等价物是什么? 【发布时间】:2013-12-10 17:15:37 【问题描述】:我最近在looking 处理一些 C 代码并“翻译”为 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 *)
“keys”调用是我需要做的。看起来它正在对字符串进行按位运算。
我设法找到了与上述等效的 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 *)
【问题讨论】:
在第二个示例中,宏不是将某些堆栈常量“键”的地址或地址放入您的结果中吗?似乎宏不是为评估 char *...而构建的... 它肯定是在字符串键上做的,虽然我不确定如何;它甚至可以编译和运行!我链接到的线程中有一点背景;这是供应商提供的样本:link。它给了我一个神奇的数字 -444763391,我试图弄清楚如何而不是硬编码。 【参考方案1】:'keys'
是一个整数字符常量(包含四个字符),其值由实现定义。您说 C 代码 _IOR('keys', 1, unsigned char *)
返回的值是 -444763391,即 4 字节十六进制数 0xE57D7301。由此我们可以得出结论,此实现从'k'<<24|'e'<<16|'y'<<8|'s'
计算'keys'
的整数值0x6B657973。 _IOR
值 0xE57D7301 来自表达式
2<<30|4<<16|'keys'<<8|1
: : : :
: : : 1 = num n
: : 'keys' = group g
: 4 = sizeof (unsigned char *)
2 = _IOC_READ
- 请注意,只有 8 位是为 TYPE(组)值保留的,而这种创造性地使用 32 位值会使 TYPE 溢出到 SIZE 和 DIR 位(与它们进行或运算)及其最高有效字节(由'k'<<24
产生)甚至被移出int
值。
使用您的 Python 函数,您可以通过调用计算相同的值
_IOR(ord('e')<<16|ord('y')<<8|ord('s'), 1, 4)
(因为k
丢失了,我们可以直接删除它)。
【讨论】:
【参考方案2】:不能保证您在 char* 上运行所获得的数字是任何特定数字。在计算keys
的_IOR 时,宏将字符串的地址视为整数。结果将根据keys
在堆栈中的位置而变化。因此,在 Python 中这个功能确实没有很好的替代品。
来自docs for _IOR(g, n, t):
g 指定此 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
分配,我认为这不会成为问题。
【讨论】:
此答案中的基本错误是将'keys'
视为字符串,但事实并非如此;它是一个包含多个字符的整数字符常量。以上是关于Python 中的 C _IOR 函数的等价物是啥?的主要内容,如果未能解决你的问题,请参考以下文章
Python 习语“if __name__ == '__main__'”的 clojure 等价物是啥?
Matlab 的 tic 和 toc 函数的 Python 等价物是啥?
Excel 的 Beta 发行版的 Python 等价物是啥?