Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
387 views
in Technique[技术] by (71.8m points)

winapi - Problems about python ctypes module

Just trying to mess around and learn about python ctypes according to the official documentation at https://docs.python.org/3.8/library/ctypes.html

Everything works just fine until:

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)
>>>

quoted from official documentaion, while i get is:

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

according to those MS documentation, seems these function calls work just fine

What's more, I also tried to mess around with the argument number so as to raise a ValueError, but that's what I get:

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

Seems the last two function calls does return null as there was an error, but no Value error exception. The only error i got is OSError, just as the documentation example shows.

Can anyone explain this? I create virtual environment using conda and I test these codes both in python 3.6.12 and python 3.8.5.

And by the way ,according to the documentation: "ValueError is raised when you call an stdcall function with the cdecl calling convention, or vice versa", I wonder what exactly "call an stdcall function with cdecl calling convention" means? Maybe just by giving different number of arguments rather than the function required?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

__stdcall and _cdecl have no difference on 64-bit compilers. There is only one calling convention and the notations are ignored and both WinDLL and CDLL work. 32-bit code is where it matters and the correct one must be used.

You should still use the appropriate WinDLL or CDLL in scripts if you want the script to work correctly on both 32-bit and 64-bit Python.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...