在Python(2.7.3)代码中,我尝试使用ioctl调用,接受long int(64位)作为参数。我使用的是64位系统,所以64位int的大小与指针大小相同。在
我的问题是Python似乎不接受64位int作为fcntl.ioctl公司()调用。它很乐意接受32位int或64位指针-但我需要传递一个64位int。
这是我的ioctl处理程序:
static long trivial_driver_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
long err = 0;
switch (cmd)
{
case 1234:
printk("=== (%u) Driver got arg %lx; arg<<32 is %lx\n", cmd, arg, arg<<32);
break;
case 5678:
printk("=== (%u) Driver got arg %lx\n", cmd, arg);
break;
default:
printk("=== OH NOES!!! %u %lu\n", cmd, arg);
err = -EINVAL;
}
return err;
}
在现有的C代码中,我使用如下调用:
^{pr2}$在python中,我打开设备文件,然后得到以下结果:
>>> from fcntl import ioctl
>>> import os
>>> fd = os.open (DEV_NAME, os.O_RDWR, 0666)
>>> ioctl(fd, 1234, 0xffff)
0
>>> arg = 0xffff<<32
>>> # Kernel log: === (1234) Driver got arg ffff; arg<<32 is ffff00000000
>>> # This demonstrates that ioctl() happily accepts a 32-bit int as an argument.
>>> import struct
>>> ioctl(fd, 5678, struct.pack("L",arg))
'\x00\x00\x00\x00\xff\xff\x00\x00'
>>> # Kernel log: === (5678) Driver got arg 7fff9eb1fcb0
>>> # This demonstrates that ioctl() happily accepts a 64-bit pointer as an argument.
>>> ioctl(fd, 5678, arg)
Traceback (most recent call last):
File "<pyshell#10>", line 1, in <module>
ioctl(fd, 5678, arg)
OverflowError: signed integer is greater than maximum
>>> # Kernel log: (no change - OverflowError is within python)
>>> # Oh no! Can't pass a 64-bit int!
>>>
Python有什么方法可以将我的64位参数传递给ioctl()?
Python的
ioctl
中的“arg”符号与C的符号不同在python中(同样根据1),它要么是python整数(不指定32位或64位),要么是某种缓冲区对象(如字符串)。在Python中并没有真正的“指针”(所以所有的底层架构细节——比如32位或64位地址)都被完全隐藏了。在
如果我理解正确的话,您需要的是一个
SET_VAL
是struct.pack(your 64-bit integer)
的字符串,然后将这个字符串传递给ioctl,而不是直接传递整数。在像这样:
struct.pack('>Q',1<<32)
对于
GET_VAL
,您需要再次使用“Q”类型(而不是“L”)来正确解压64位整数值。在使用Python的} 的以下测试。。。在
fcntl.ioctl()
是否可以实现这一点取决于系统。通过源代码跟踪,错误消息来自对line 658 of ^{…在我的系统上,
^{pr2}$/usr/include/limits.h
告诉我。。。在…大概是
(2 ** ((sizeof(int) * 8) - 1)) - 1
。在因此,除非您正在使用的系统中},否则您必须直接使用^{} 模块调用底层的C函数,但它是特定于平台的。在
sizeof(int)
至少是{假设是Linux,类似这样的东西应该可以工作。。。在
相关问题 更多 >
编程相关推荐