Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: eryk sun Newsgroups: comp.lang.python Subject: Re: python, ctypes and GetIconInfo issue Date: Fri, 6 May 2016 18:38:49 -0500 Lines: 71 Message-ID: References: <1868a625-af1e-4937-a9ec-5ccf7710d48b@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-Trace: news.uni-berlin.de GzIDnNa1E/kdQHoHFDJWcwP+VggeHuHkss9FzOCZTTZg== Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'calls.': 0.07; 'classes.': 0.07; 'incompatible': 0.07; 'repeated': 0.07; 'truncated': 0.07; "%s'": 0.09; '[1]:': 0.09; '[2]:': 0.09; 'bool': 0.09; 'docs.': 0.09; 'int.': 0.09; 'issue?': 0.09; 'pointers': 0.09; 'subject:ctypes': 0.09; 'example:': 0.10; 'python': 0.10; 'assume': 0.11; 'subject:python': 0.14; 'missed': 0.15; '2016': 0.16; '__del__': 0.16; 'caches': 0.16; 'caching': 0.16; 'configuring': 0.16; 'ctype': 0.16; 'hint': 0.16; 'instantiates': 0.16; "module's": 0.16; "others'": 0.16; 'pointers.': 0.16; 'prototypes.': 0.16; 'received:io': 0.16; 'received:psf.io': 0.16; 'restype': 0.16; 'stepping': 0.16; 'subject:issue': 0.16; 'wrote:': 0.16; 'instance,': 0.18; 'library,': 0.18; 'pointer': 0.18; 'skip:u 30': 0.18; 'library': 0.20; 'windows': 0.20; 'cc:2**0': 0.20; 'work,': 0.21; 'not,': 0.22; '64-bit': 0.22; 'ctypes': 0.22; 'libraries': 0.22; 'referring': 0.22; 'cc:no real name:2**0': 0.22; 'am,': 0.23; 'wrote': 0.23; "haven't": 0.24; 'cc:addr:gmail.com': 0.24; 'examples': 0.24; 'implemented': 0.24; 'header:In-Reply-To:1': 0.24; 'feature': 0.24; "i've": 0.25; "doesn't": 0.26; 'example': 0.26; 'fri,': 0.27; 'message- id:@mail.gmail.com': 0.27; '[2]': 0.27; 'specify': 0.27; 'function': 0.28; 'this.': 0.28; 'skip:u 20': 0.28; '32-bit': 0.29; 'era': 0.29; "i'm": 0.30; 'code': 0.30; 'skip:g 30': 0.30; 'checked': 0.31; "can't": 0.32; 'included': 0.32; '[1]': 0.32; 'url:python': 0.33; 'windows.': 0.33; 'case,': 0.34; 'covered': 0.34; 'handle': 0.34; 'info': 0.34; 'received:google.com': 0.35; 'instance': 0.35; 'something': 0.35; "isn't": 0.35; 'but': 0.36; 'url:org': 0.36; 'received:209.85': 0.36; 'loaded': 0.36; 'to:addr :python-list': 0.36; 'subject:: ': 0.37; 'turn': 0.37; 'received:209.85.213': 0.37; 'received:209': 0.38; 'anything': 0.38; 'several': 0.38; 'to:addr:python.org': 0.40; 'where': 0.40; 'some': 0.40; 'your': 0.60; 'skip:u 10': 0.61; 'avoid': 0.61; 'caused': 0.61; 'real': 0.62; 'thomas': 0.63; 'reuse': 0.66; 'potentially': 0.67; 'talking': 0.67; 'subject.': 0.72; 'address,': 0.77; 'miss': 0.77; 'url:cpython': 0.84 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=Ck0+yZbNiRlB3thCZDmM5K1v6xudJ3mFm0TY0c1wEA0=; b=SXQwHo8VfmgpTotIlIJWck+OsKORGWfZOWJIkh/DeO+S4I5UrlNdUY+BOy2hex7XLa /eHKl/LHrt9z1CGuE4cmtgUyIp49QV0Vl/LtnuNHOemUlK5nhgcryyekOo3lKKMzC1ni snYK7zQoXUEqQn/JWrYNyzkdhz5dOib5OdRzkbE5rcBu8NQI54Q8VSGHqTgNJtpxMNGe EqVCge73Ho99G++O2bMkMVfoGf4aX73BzViT2y0KbWQoQaTvKRKz1exPq3mPNR2+2hrw HdA8w44AkRO+cTENlyYKPV59lWyDQetiKlVUR2+hVqKNLnmJeEEpeyPg9hxrJi3vTmQ6 /suA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=Ck0+yZbNiRlB3thCZDmM5K1v6xudJ3mFm0TY0c1wEA0=; b=f1KP/Edk9l0i4EfF2RVd3i/k081kzZHKtbxX/1N5cXhHf+Xz4yvNFx8sCuhueaX0jE gpoPZh9y3LD1t/dkN6hkoCzWjKwjs800sRPGrjG/+erJ+OWOGUo8JZH4kXu26a5SNxV/ eaienPsfwk6RZsYuqUYOHkxIBV4Rd6W2hfImAZEmhmsJyQnBa3rQLpSyfNzqpX7mHXNe DvMdhgWPnaRj6XjQKlic345UlUJDjqg+Kq6oMgIZBlqL8zqRE/teYBlH9/lMhURPcWgm CgS6DjU26+No/Zpv+b/IjPaKUAj47MZglo5115H03ig/psbBo1fhfJz3xSoFZhq+/B4g AHYw== X-Gm-Message-State: AOPr4FXcvxCUSy18OJSjwi+8+Dl8+gZ9VBa66F8minhQYhx5YacBgd61tPGNj3/ZmhXzJQ6u5B8gLuYxXI4I/w== X-Received: by 10.50.29.73 with SMTP id i9mr249786igh.32.1462577968802; Fri, 06 May 2016 16:39:28 -0700 (PDT) In-Reply-To: <1868a625-af1e-4937-a9ec-5ccf7710d48b@googlegroups.com> X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Mailman-Original-Message-ID: X-Mailman-Original-References: <1868a625-af1e-4937-a9ec-5ccf7710d48b@googlegroups.com> Xref: csiph.com comp.lang.python:108245 On Fri, May 6, 2016 at 8:36 AM, 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)