所以看完答案后 答案一 和 答案二我很好奇,为什么总是要设置为 argtype
的函数上。答案指出,你应该总是在函数上指定 argtypes
,即
my_func.argtypes = [ctypes.c_int]
my_func(1)
否则,如果你传递了错误的变量,事情可能会出错。
但我们假设我总是这样做。
my_func(ctypes.c_int(1))
这样做定义的好吗?设置 argtypes
做任何事情都会比总是指定的那样做更多。ctypes
的参数(除了提供更少的类型)?
这很好定义,只要你每次都正确地键入就可以了。 当你指定 .argtypes
它为你做构造,每次都用同样的方法,并检查指针或用户手动构造的类型是否符合声明的类型,以及参数的数量是否至少是定义的数量。
真的,你宁愿用 my_func(1)
或 my_func(ctypes.c_int(1))
??my_func(ctypes.c_float(1.5))
不会失败,如果参数应该是一个 ctypes.c_int
但它会,如果 my_func.argtypes = ctypes.c_int,
.
考虑模块中的一个C函数 x
要想 int
并返回 int
:
>>> from ctypes import *
>>> x = CDLL('x')
>>> x.test() # forgot to pass a parameter. Garbage...
1983836396
>>> x.test(1.5) # ctypes knows Python float is ambiguous (C float or double?)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ctypes.ArgumentError: argument 1: <class 'TypeError'>: Don't know how to convert parameter 1
>>> x.test(c_float(1.5)) # But now, garbage...
1069547520
>>> x.test('hello') # garbage...
1197125872
>>> x.test(b'hello') # garbage...
1202177960
>>> x.test(5) # oh, got it right this time.
5
对比:
>>> x.test.argtypes = c_int,
>>> x.test()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: this function takes at least 1 argument (0 given)
>>> x.test(1.5)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type
>>> x.test('hello')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type
>>> x.test(b'hello')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type
>>> x.test(c_float(1.5))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type
>>> x.test(5) # MUST pass correctly.
5