On Fri, May 6, 2016 at 8:36 AM, <mymy...@gmail.com> wrote: > >> 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?
You haven't missed anything in the documentation. The ctypes docs need work, and some of the examples are bad, if not wrong. For example, the GetModuleHandleA examples incorrectly handle the pointer result because they were never updated for 64-bit Windows. One can't use a Python function as the restype with a C function that returns a pointer because it will be truncated to a C int. Whoever wrote the GetModuleHandleA examples either doesn't know how this feature is implemented in ctypes (probably not, since I think Thomas Heller wrote the example), or doesn't know that a Windows HMODULE is a pointer to the module's base address, or was just writing sloppy code in the era of 32-bit Windows. In this case, look at the CDLL [1] and LibraryLoader [2] classes. Note how CDLL.__getattr__ caches function pointers using setattr(self, name, func). Note how LibraryLoader.__getattr__ caches libraries using setattr(self, name, dll), and how it instantiates the library using self._dlltype(name), with no way to specify use_last_error=True. This has caused real problems for projects such as colorama (fixed) and pyreadline (still broken), and I've seen potential problems in several other projects that naively copy the cdll and windll examples from the docs. It's not their fault. The docs are just bad on this subject. [1]: https://hg.python.org/cpython/file/v3.5.1/Lib/ctypes/__init__.py#l314 [2]: https://hg.python.org/cpython/file/v3.5.1/Lib/ctypes/__init__.py#l410 >> 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? I'm talking about reusing an instance, to avoid the cost of repeated allocation and deallocation. For example: info = ICONINFOEX() for hIcon in hIcons: user32.GetIconInfoExW(hIcon, ctypes.byref(info)) print('fIcon : %d' % info.fIcon) print('wResID : %d' % info.wResID) print('szModName: %s' % info.szModName) gdi32.DeleteObject(info.hbmMask) gdi32.DeleteObject(info.hbmColor) -- https://mail.python.org/mailman/listinfo/python-list