Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/325.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.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 ctypes包装函数接受int无法拒绝大于int_MAX的参数_Python_C_Ctypes - Fatal编程技术网

Python ctypes包装函数接受int无法拒绝大于int_MAX的参数

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来测试代码

在64位Linux上使用Python 2.7.13进行测试

在共享对象中有一个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