Python ctypes包装函数接受int无法拒绝大于int_MAX的参数
在64位Linux上使用Python 2.7.13进行测试 在共享对象中有一个C函数。此函数接受两个Python ctypes包装函数接受int无法拒绝大于int_MAX的参数,python,c,ctypes,Python,C,Ctypes,在64位Linux上使用Python 2.7.13进行测试 在共享对象中有一个C函数。此函数接受两个ints并返回一个int。当我尝试从Python端传递一个大于INT\u MAX但仍然可以表示为无符号INT的整数时,我没有得到我所期望的Python端异常 // add.c int add(int a, int b) { return a + b; } 使用以下选项将此文件编译为共享对象。(来自makefile的片段) 我正在使用下面的python脚本test\u add.c来测试代码
int
s并返回一个int
。当我尝试从Python端传递一个大于INT\u MAX
但仍然可以表示为无符号INT的整数时,我没有得到我所期望的Python端异常
// add.c
int add(int a, int b)
{
return a + b;
}
使用以下选项将此文件编译为共享对象。(来自makefile的片段)
我正在使用下面的python脚本test\u add.c
来测试代码。我可能做了更多的工作,手动提供ctypes.c_int
的参数类型,并手动强制假设生成的整数,但似乎这些操作都不应该导致我看到的行为
下面是我正在尝试的主要测试,使用不同的x
和y
值。失败测试用例的一个例子是x=0
和y=2147483648
,一个比INT\u MAX
大的数字
try:
s = add(ctypes.c_int(x), ctypes.c_int(y))
except Exception:
return
# if no exception was thrown, python and C should agree
# about the result of the addition
assert s == (x + y)
为了完整起见,下面是完整的脚本:
import ctypes
import os.path
import unittest
from hypothesis import given
import hypothesis.strategies as st
# import shared object from this directory
addso_path = os.path.dirname(os.path.abspath(__file__)) + os.path.sep + "add.so"
addso = ctypes.cdll.LoadLibrary(addso_path)
# extract add symbol, explicitly force its argument types to be
# (int, int)
# and return type to be
# int
add = addso.add
add.argtypes = [ctypes.c_int, ctypes.c_int]
add.restype = ctypes.c_int
class TestAddition(unittest.TestCase):
@given(x=st.integers(), y=st.integers())
def test_add(self, x, y):
# if we catch any error on the python side,
# then that counts as successfully preventing an
# out-of-bounds integer before it is passed to C
try:
s = add(ctypes.c_int(x), ctypes.c_int(y))
except Exception:
return
# if no exception was thrown, python and C should
# agree about the result of the addition
assert s == (x + y)
if __name__ == "__main__":
unittest.main()
以下是测试套件的输出:
Falsifying example: test_add(self=<__main__.TestAddition testMethod=test_add>, x=0, y=2147483648)
F
======================================================================
FAIL: test_add (__main__.TestAddition)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_add.py", line 22, in test_add
def test_add(self, x, y):
File "/.../opt/c-add/venv/lib/python2.7/site-packages/hypothesis/core.py", line 525, in wrapped_test
print_example=True, is_final=True
File "/...opt/c-add/venv/lib/python2.7/site-packages/hypothesis/executors.py", line 58, in default_new_style_executor
return function(data)
File "/.../opt/c-add/venv/lib/python2.7/site-packages/hypothesis/core.py", line 112, in run
return test(*args, **kwargs)
File "test_add.py", line 33, in test_add
assert s == (x + y)
AssertionError
伪造示例:测试添加(self=,x=0,y=2147483648)
F
======================================================================
失败:测试添加(主测试添加)
----------------------------------------------------------------------
回溯(最近一次呼叫最后一次):
文件“test_add.py”,test_add中的第22行
def测试_添加(自身、x、y):
文件“/…/opt/c-add/venv/lib/python2.7/site packages/hypothesis/core.py”,第525行,在包装测试中
print_example=True,is_final=True
文件“/…opt/c-add/venv/lib/python2.7/site packages/hyporation/executors.py”,第58行,默认为新样式的executor
返回函数(数据)
文件“/…/opt/c-add/venv/lib/python2.7/site packages/hypothesis/core.py”,第112行,运行中
返回测试(*args,**kwargs)
文件“test_add.py”,test_add中第33行
断言s==(x+y)
断言错误
注意:“未进行溢出检查”。因此,您的(输入)long将被静默地“转换”(截断,2-补码包装,无论什么)为int,并且C中的加法将从那里继续。另请参见-正如@Evert所说,ctypes本身不进行溢出检查。要获得ctypes类型的位(以及字节)大小,请参见@torek,是否有一个深层次的原因可以解释为什么ctypes在转换为ctypes时(比如ctypes.c_int
)无法移植检查超出范围的Python数字,或者它只是不检查?据我所知,没有理由不能,只是不能。
Falsifying example: test_add(self=<__main__.TestAddition testMethod=test_add>, x=0, y=2147483648)
F
======================================================================
FAIL: test_add (__main__.TestAddition)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_add.py", line 22, in test_add
def test_add(self, x, y):
File "/.../opt/c-add/venv/lib/python2.7/site-packages/hypothesis/core.py", line 525, in wrapped_test
print_example=True, is_final=True
File "/...opt/c-add/venv/lib/python2.7/site-packages/hypothesis/executors.py", line 58, in default_new_style_executor
return function(data)
File "/.../opt/c-add/venv/lib/python2.7/site-packages/hypothesis/core.py", line 112, in run
return test(*args, **kwargs)
File "test_add.py", line 33, in test_add
assert s == (x + y)
AssertionError