@@ -178,23 +178,13 @@ handle (passing ``None`` as single argument to call it with a ``NULL`` pointer):
178178 0x1d000000
179179 >>>
180180
181- :exc: `ValueError ` is raised when you call an ``stdcall `` function with the
182- ``cdecl `` calling convention, or vice versa::
183-
184- >>> cdll.kernel32.GetModuleHandleA(None) # doctest: +WINDOWS
185- Traceback (most recent call last):
186- File "<stdin>", line 1, in <module>
187- ValueError: Procedure probably called with not enough arguments (4 bytes missing)
188- >>>
189-
190- >>> windll.msvcrt.printf(b"spam") # doctest: +WINDOWS
191- Traceback (most recent call last):
192- File "<stdin>", line 1, in <module>
193- ValueError: Procedure probably called with too many arguments (4 bytes in excess)
194- >>>
195-
196- To find out the correct calling convention you have to look into the C header
197- file or the documentation for the function you want to call.
181+ :mod: `!ctypes ` cannot determine a function's calling convention or signature.
182+ Consult the function's C header file or documentation to choose the correct calling
183+ convention and set the :attr: `~_CFuncPtr.argtypes ` attribute, as described in
184+ :ref: `ctypes-specifying-required-argument-types `. Without
185+ :attr: `~_CFuncPtr.argtypes `, the number of arguments is not checked. Calling a
186+ function with an incorrect calling convention or with incorrect arguments can
187+ corrupt memory or crash Python.
198188
199189On Windows, :mod: `!ctypes ` uses win32 structured exception handling to prevent
200190crashes from general protection faults when functions are called with invalid
@@ -586,6 +576,20 @@ prototype for a C function), and tries to convert the arguments to valid types::
586576 13
587577 >>>
588578
579+ Setting :attr: `~_CFuncPtr.argtypes ` also causes :mod: `!ctypes ` to raise
580+ :exc: `TypeError ` if too few arguments are passed::
581+
582+ >>> printf(b"%s %d %f\n", b"X", 2)
583+ Traceback (most recent call last):
584+ File "<stdin>", line 1, in <module>
585+ TypeError: this function takes at least 4 arguments (3 given)
586+
587+ Functions using the ``stdcall `` calling convention require exactly as many
588+ arguments as there are items in :attr: `~_CFuncPtr.argtypes `. Functions using
589+ the ``cdecl `` calling convention accept additional arguments, to support
590+ variadic functions. The declaration must match the function's actual signature;
591+ ctypes cannot verify this.
592+
589593If you have defined your own classes which you pass to function calls, you have
590594to implement a :meth: `~_CData.from_param ` class method for them to be able to use them
591595in the :attr: `~_CFuncPtr.argtypes ` sequence. The :meth: `~_CData.from_param ` class method receives
@@ -1970,10 +1974,11 @@ in :mod:`!ctypes`) which inherits from the private :class:`_CFuncPtr` class:
19701974 .. attribute :: argtypes
19711975
19721976 Assign a tuple of ctypes types to specify the argument types that the
1973- function accepts. Functions using the ``stdcall `` calling convention can
1974- only be called with the same number of arguments as the length of this
1975- tuple; functions using the C calling convention accept additional,
1976- unspecified arguments as well.
1977+ function accepts. :exc: `TypeError ` is raised if the function is called
1978+ with fewer arguments than the length of this tuple. Functions using the
1979+ ``stdcall `` calling convention also raise :exc: `TypeError ` if called with
1980+ more arguments; functions using the ``cdecl `` calling convention accept
1981+ additional, unspecified arguments as well.
19771982
19781983 When a foreign function is called, each actual argument is passed to the
19791984 :meth: `~_CData.from_param ` class method of the items in the :attr: `argtypes `
0 commit comments