Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.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
关于pythonctypes模块的问题_Python_Winapi_Ctypes_Kernel32 - Fatal编程技术网

关于pythonctypes模块的问题

关于pythonctypes模块的问题,python,winapi,ctypes,kernel32,Python,Winapi,Ctypes,Kernel32,根据官方的文档,我只是想混时间学习一下python的ctypes 一切正常,直到: ValueError在使用cdecl调用约定调用stdcall函数时引发,反之亦然: 根据这些MS文档,这些函数调用似乎工作得很好 更重要的是,我还试图弄乱参数编号,以引起ValueError,但我得到的是: >>> cdll.kernel32.GetModuleHandleA(None,0,0) 1374486528 >>> windll.kernel32.GetModul

根据官方的文档,我只是想混时间学习一下python的ctypes

一切正常,直到:

ValueError在使用cdecl调用约定调用stdcall函数时引发,反之亦然:

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

更重要的是,我还试图弄乱参数编号,以引起ValueError,但我得到的是:

>>> cdll.kernel32.GetModuleHandleA(None,0,0) 
1374486528
>>> windll.kernel32.GetModuleHandleA(0,0,0) 
1374486528
>>> windll.kernel32.GetModuleHandleA() 
0
>>> cdll.kernel32.GetModuleHandleA() 
0
似乎最后两个函数调用确实返回null,因为存在错误,但没有值错误异常。 我得到的唯一错误是OSError,正如文档示例所示

有人能解释一下吗?我使用conda创建虚拟环境,并在python 3.6.12和python 3.8.5中测试这些代码


顺便说一句,根据文档:“当您使用cdecl调用约定调用stdcall函数时会引发ValueError,反之亦然”,我想知道“使用cdecl调用约定调用stdcall函数”到底意味着什么?可能只是给出不同数量的参数,而不是所需的函数?

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


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

看起来像是一些未定义的行为。如果医生没有明确说明,那么任何事情都有可能发生,明白了吗。但是你能解释一下“stdcall和cdecl在64位编译器上没有区别”吗?这是否意味着对于两种调用约定,编译器总是生成相同的代码?作为这两种调用约定之间的主要区别,堆栈清理作业会发生什么变化?@RemiBall Google
x64 ABI
(应用程序二进制接口)。有一个很好的概述。
>>> cdll.kernel32.GetModuleHandleA(None) 
1374486528
>>> windll.msvcrt.printf(b"spam") 
4
>>> cdll.kernel32.GetModuleHandleA(None,0,0) 
1374486528
>>> windll.kernel32.GetModuleHandleA(0,0,0) 
1374486528
>>> windll.kernel32.GetModuleHandleA() 
0
>>> cdll.kernel32.GetModuleHandleA() 
0