python, ctypes and GetIconInfo issue
mymyxin at gmail.com
mymyxin at gmail.com
Fri May 6 09:36:03 EDT 2016
Hello eryk sun,
first of all thank you very much, really appreciate your help.
Please be informed that I'm a python beginner, so forgive me if
my following questions sound stupid (also I'm not a native speaker).
> Please avoid windll. It caches the loaded library, which in turn
> caches function pointers. So all packages that use windll.user32 are
> potentially stepping on each others' toes with mutually incompatible
> function prototypes. It also doesn't allow configuring
> use_last_error=True to enable ctypes.get_last_error() for WinAPI
> function calls.
I assume you are referring to this block of code
GetIconInfo = windll.user32.GetIconInfo
GetIconInfo.argtypes = [HICON, POINTER(ICONINFO)]
GetIconInfo.restype = BOOL
GetIconInfo.errcheck = ErrorIfZero
where as you use
user32 = ctypes.WinDLL('user32', use_last_error=True)
user32.GetIconInfoExW.errcheck = check_bool
user32.GetIconInfoExW.restype = wintypes.BOOL
user32.GetIconInfoExW.argtypes = (
wintypes.HICON, # _In_ hIcon
PICONINFOEX,) # _Out_ piconinfoex
I've checked ctype docu included in python but don't find any hint about your concerns.
May I ask you, do you know additional documents/sites which I can use to get a better understanding
about caching issue? Or did I miss something from used documentation?
> The attribute name is "_fields_", not "__fields__", so you haven't
> actually defined any fields and sizeof(ICONINFO) is 0. When you pass
> this empty struct to GetIconInfo, it potentially overwrites and
> corrupts existing data on the heap that can lead to a crash later on.
Ahhh, typically me. Thank you for pointing to it.
> Here's the setup I created to test GetIconInfo and GetIconInfoEx.
> Maybe you can reuse some of this code, but if you're using XP this
> won't work as written because GetIconInfoEx was added in Vista.
> Note the use of a __del__ finalizer to call DeleteObject on the
> bitmaps. Otherwise, in a real application, calling GetIconInfo would
> leak memory.
Oh, you answered already an upcoming question I guess, thank you ;-)
> Using __del__ is convenient, but note that you can't
> reuse an instance without manually calling DeleteObject on the
> bitmaps.
Don't understand this. Isn't this covered by your example in base class?
class ICONINFO_BASE(ctypes.Structure):
def __del__(self, gdi32=gdi32):
if self.hbmMask:
gdi32.DeleteObject(self.hbmMask)
self.hbmMask = None
if self.hbmColor:
gdi32.DeleteObject(self.hbmColor)
self.hbmColor = None
If I would do somthing like
iconinfoex = ICONINFOEX()
iconinfoex = None
DeleteObject would be called once None gets assigned, wouldn't it?
Again, thank you very much.
Hubert
More information about the Python-list
mailing list