Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x Python3上的ctypes函数调用失败_Python 3.x_Ctypes - Fatal编程技术网

Python 3.x Python3上的ctypes函数调用失败

Python 3.x Python3上的ctypes函数调用失败,python-3.x,ctypes,Python 3.x,Ctypes,我有一段调用libc函数的代码: import sys import ctypes libc = ctypes.CDLL('libc.so.6') class CpuSet(ctypes.Structure): _fields_ = [('bits', ctypes.c_ulonglong * 16)] print(ctypes.sizeof(CpuSet)) cpu_set = CpuSet() tid = int(sys.argv[1]) rc = libc.sched_geta

我有一段调用libc函数的代码:

import sys
import ctypes
libc = ctypes.CDLL('libc.so.6')

class CpuSet(ctypes.Structure):
    _fields_ = [('bits', ctypes.c_ulonglong * 16)]

print(ctypes.sizeof(CpuSet))
cpu_set = CpuSet()
tid = int(sys.argv[1])
rc = libc.sched_getaffinity(int(tid), ctypes.sizeof(CpuSet), ctypes.addressof(cpu_set))
print(rc)
当我用Python2运行它时,我得到了一个成功的rc“0”,当用Python3运行它时,打印的rc是-1。errno值设置为EFAULT,根据,表示“提供的内存地址无效”。但是,
ctypes.addressof(cpu\u set)
似乎返回了一个有效的指针。为了安全起见,我打印了sizeof值,两个python上都是128

# python3 /tmp/test.py 2740
128
-1
# python2 /tmp/test.py 2740
128
0
# python2 -V
Python 2.6.6
# python3 -V
Python 3.8.1
我在这两种情况下都在root下运行代码

你知道为什么会发生这种情况,或者我可以进行哪些进一步的测试吗

更新:我用strace运行了两条蟒蛇,但有一点不同:

# strace python2 /tmp/test.py 17526 2>&1 | grep sched_getaffinity
sched_getaffinity(17526, 128, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]) = 8
# strace python3 /tmp/test.py 17526 2>&1 | grep sched_getaffinity
sched_getaffinity(17526, 128, 0x1da22030) = -1 EFAULT (Bad address)
看起来Python3传递了错误的指针?或者结构没有初始化?还是不确定。

找到了

我打印了
ctypes.addressof
的返回值,并注意到在python 3中,指针被截断:

# strace -e raw=sched_getaffinity python3 /tmp/test.py 2740 2>&1 | grep 'getaffini\|addressof'
write(1, "128\naddressof cpuset: 0x7fabee87"..., 37128
addressof cpuset: 0x7fabee8710b0
sched_getaffinity(0xab4, 0x80, 0xee8710b0) = -1 (errno 14)
这在python 2中没有发生,可能是因为指针适合32位:

# strace -e raw=sched_getaffinity python2 /tmp/test.py 2740 2>&1 | grep 'getaffini\|addressof'
write(1, "128\naddressof cpuset: 0x193aae0\n", 32128
addressof cpuset: 0x193aae0
sched_getaffinity(0xab4, 0x80, 0x193aae0) = 0x8
再次查看文档,我发现传递指针的推荐方法是使用而不是
addressof
。我将代码改为使用
byref
,它成功了:

# strace -e raw=sched_getaffinity python3 /tmp/test.py 2740 2>&1 | grep 'getaffini\|addressof'
write(1, "128\naddressof cpuset: 0x7fb5d46f"..., 37128
addressof cpuset: 0x7fb5d46fb0b0
sched_getaffinity(0xab4, 0x80, 0x7fb5d46fb0b0) = 0x8

不确定从addressof返回的值被截断的原因。也许将其转换为指针类型也会起作用?

ctypes假设整数以32位的形式传递,指针根据体系结构大小传递
addressof
返回整数地址,如果体系结构为64位且参数未声明为指针,则在堆栈上传递时会被截断。为函数设置
.argtypes
.restype
,以避免出现问题,并允许
ctypes
执行更好的错误检查。