关于 python ctypes 模块的问题

Problems about python ctypes module

只是想根据 https://docs.python.org/3.8/library/ctypes.html

上的官方文档了解 python ctypes

一切正常,直到:

ValueError is raised when you call an stdcall function with the cdecl calling convention, or vice versa:

>>> cdll.kernel32.GetModuleHandleA(None)  
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Procedure probably called with not enough arguments (4 bytes missing)
>>>

>>> windll.msvcrt.printf(b"spam")  
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Procedure probably called with too many arguments (4 bytes in excess)
>>>

引用自官方文档,而我得到的是:

>>> cdll.kernel32.GetModuleHandleA(None) 
1374486528
>>> windll.msvcrt.printf(b"spam") 
4

根据那些 MS 文档,这些函数调用似乎工作得很好

此外,我还试图弄乱参数编号以引发 ValueError,但这就是我得到的结果:

>>> cdll.kernel32.GetModuleHandleA(None,0,0) 
1374486528
>>> windll.kernel32.GetModuleHandleA(0,0,0) 
1374486528
>>> windll.kernel32.GetModuleHandleA() 
0
>>> cdll.kernel32.GetModuleHandleA() 
0

似乎最后两个函数调用确实 return null 因为有错误,但没有值错误异常。 正如文档示例所示,我遇到的唯一错误是 OSError。

谁能解释一下?我使用 conda 创建虚拟环境,并在 python 3.6.12 和 python 3.8.5.

中测试这些代码

顺便说一下,根据文档:“当您使用 cdecl 调用约定调用 stdcall 函数时会引发 ValueError,反之亦然”,我想知道“使用 cdecl 调用约定调用 stdcall 函数”到底是什么方法?也许只是通过提供不同数量的参数而不是所需的功能?

__stdcall_cdecl 在 64 位编译器上没有区别。只有一个调用约定,符号被忽略,WinDLL 和 CDLL 都可以工作。 32 位代码很重要,必须使用正确的代码。

如果您希望脚本在 32 位和 64 位上都能正常工作,您仍然应该在脚本中使用适当的 WinDLL 或 CDLL Python。