Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #108246

Re: python, ctypes and GetIconInfo issue

Path csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail
From eryk sun <eryksun@gmail.com>
Newsgroups comp.lang.python
Subject Re: python, ctypes and GetIconInfo issue
Date Fri, 6 May 2016 18:39:04 -0500
Lines 122
Message-ID <mailman.441.1462577987.32212.python-list@python.org> (permalink)
References <f02f269a-703c-42c6-9419-0a8e667bd6b0@googlegroups.com> <CACL+1atJ+aP1zbMukcqszWC6ycizvjKu+4oc41K1WGmu0-kfXg@mail.gmail.com> <mailman.419.1462493404.32212.python-list@python.org> <5dd5db3e-ffa9-4c7b-9385-dc20f85dd45b@googlegroups.com> <CACL+1av9OSbmeunBGuk2rsFz0mcoX+sgfVdi6oFRZpNxGyApyA@mail.gmail.com>
Mime-Version 1.0
Content-Type text/plain; charset=UTF-8
X-Trace news.uni-berlin.de 2lMEPnxbf+nwS5MXwhELRArKZuM1A3Fly6QWp5Gb/C3Q==
Return-Path <eryksun@gmail.com>
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; 'classes,': 0.05; 'initialize': 0.05; '#include': 0.07; 'append': 0.07; 'array.': 0.07; 'bug.': 0.07; 'classes.': 0.07; 'url:msdn': 0.07; '[1]:': 0.09; '[2]:': 0.09; '[3]:': 0.09; 'aborted': 0.09; 'argument,': 0.09; 'below).': 0.09; 'dict': 0.09; 'falls': 0.09; 'subclass': 0.09; 'subject:ctypes': 0.09; 'typedef': 0.09; 'bug': 0.10; 'def': 0.13; 'subject:python': 0.14; 'argument': 0.15; 'properly': 0.15; 'value.': 0.15; '%d,': 0.16; "('b',": 0.16; "('c',": 0.16; '2016': 0.16; '42,': 0.16; '[3],': 0.16; 'appends': 0.16; 'ffi': 0.16; 'ffi_type': 0.16; 'hierarchy': 0.16; 'hierarchy,': 0.16; 'pointers.': 0.16; 'received:io': 0.16; 'received:psf.io': 0.16; 'rewriting': 0.16; 'shares.': 0.16; 'similarly,': 0.16; 'storing': 0.16; 'structs': 0.16; 'subclassing': 0.16; 'subject:issue': 0.16; 'unions': 0.16; 'windows:': 0.16; 'wrote:': 0.16; 'pointer': 0.18; '>>>': 0.20; 'cc:2**0': 0.20; '(see': 0.20; 'not,': 0.22; '64-bit': 0.22; 'affects': 0.22; 'ctypes': 0.22; 'struct': 0.22; 'cc:no real name:2**0': 0.22; 'am,': 0.23; 'wrote': 0.23; 'consistent': 0.23; 'elements': 0.23; 'passing': 0.23; "haven't": 0.24; 'import': 0.24; 'cc:addr:gmail.com': 0.24; 'patch': 0.24; 'header:In-Reply-To:1': 0.24; "doesn't": 0.26; 'example': 0.26; 'checking': 0.27; 'fri,': 0.27; 'message-id:@mail.gmail.com': 0.27; 'this.': 0.28; 'crash': 0.29; 'initialized': 0.29; 'array': 0.29; 'code': 0.30; 'checks': 0.30; 'class.': 0.30; 'query': 0.30; 'skip:g 30': 0.30; 'skip:_ 10': 0.32; 'class': 0.33; 'common': 0.33; 'int': 0.33; 'case,': 0.34; 'maintaining': 0.34; 'list': 0.34; 'received:google.com': 0.35; 'instance': 0.35; 'something': 0.35; "isn't": 0.35; 'but': 0.36; 'skip:i 20': 0.36; 'received:209.85': 0.36; '(i.e.': 0.36; 'url:library': 0.36; 'to:addr:python-list': 0.36; 'subject:: ': 0.37; 'received:209.85.213': 0.37; 'itself': 0.38; 'received:209': 0.38; 'test': 0.39; 'submit': 0.39; 'to:addr:python.org': 0.40; 'some': 0.40; 'field': 0.60; 'your': 0.60; 'entire': 0.61; 'total': 0.62; 'back': 0.62; 'different': 0.63; 'information': 0.63; 'bothered': 0.66; 'cast': 0.66; 'inherit': 0.66; 'safety': 0.66; 'union': 0.67; 'levels': 0.70; 'url:en-us': 0.72; 'url:a': 0.75; '84,': 0.84; 'fields,': 0.84; 'inclusive': 0.84; 'info)': 0.84; 'shares': 0.93
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=ZHOo2L5aZHx+jExbNPEns5KSDHKN+iHFQlUPDyKHM3M=; b=HA73rYbiH8kWaymucC3poFkhbUJ6+IscFL3puTm0E8IvB7kGQ+u5mraPN16nzHZYzP B+N+YEygqs8RLZ8uNkgrNwJVEBRGcA96J0UK7ovjkrHDthL9EOqRVdqHt86CQCnjqTvy Zp4S92Eu4cdM7gDAXqVp9uWViizkpL0FvwAxxx0A9bzMXrLvnhZnz2VVA3KbbQjFdePq e8R26cnhqLFwK3WFh2EgUV4mdutmqZmh9MVVu6Q5DIv/x6y3hwnFG+sM9roGFt34+oXc H5a2liiXZz15FGBLf2vSUk3OK8eLnujqK8KRuUZS9mULOQpijf06a7V61NfVuB61SJoV NanA==
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=ZHOo2L5aZHx+jExbNPEns5KSDHKN+iHFQlUPDyKHM3M=; b=fMvUKw8ruyaipyq4SSphtUAHNoH8nrJ7lDfHUS/Gww+ZCjVJ3EoKf0uNkPLfczS8Rb gUHDemoBi4JPZiNJK9md1coq/TOtppljBtiC/LhRj9YM7RK/yMk/j6FgQhNXYZ6vH+bh 7JgN/NSC11bq5ipILdiIJ5tf2ISdPaBNmczWs2AbJinuxi6PdXebSugqn+Ge+0Bs7C04 +uDmPf/V7lBQpNtOo7ygRI56GN4Yp50T/+Ob1q34SMQBKAOkPtdor5OgvxMDNI4S6u+L us2zNDISSfJjw1iEx7yNfxPQjMo6oUQ5QSrwgKG9OkUuBGT2LmnU6v/Tx+JSCLuTuoA9 +qIA==
X-Gm-Message-State AOPr4FW8x1noiuq22r8OngkV0gNpbDjKfWOx/+FjJKIxGuIi2LYDoOrZpnztx1Qe5fRCW7b0iPCznfnsdD9FxA==
X-Received by 10.50.142.97 with SMTP id rv1mr227653igb.74.1462577984773; Fri, 06 May 2016 16:39:44 -0700 (PDT)
In-Reply-To <5dd5db3e-ffa9-4c7b-9385-dc20f85dd45b@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 <python-list.python.org>
List-Unsubscribe <https://mail.python.org/mailman/options/python-list>, <mailto:python-list-request@python.org?subject=unsubscribe>
List-Archive <http://mail.python.org/pipermail/python-list/>
List-Post <mailto:python-list@python.org>
List-Help <mailto:python-list-request@python.org?subject=help>
List-Subscribe <https://mail.python.org/mailman/listinfo/python-list>, <mailto:python-list-request@python.org?subject=subscribe>
X-Mailman-Original-Message-ID <CACL+1av9OSbmeunBGuk2rsFz0mcoX+sgfVdi6oFRZpNxGyApyA@mail.gmail.com>
X-Mailman-Original-References <f02f269a-703c-42c6-9419-0a8e667bd6b0@googlegroups.com> <CACL+1atJ+aP1zbMukcqszWC6ycizvjKu+4oc41K1WGmu0-kfXg@mail.gmail.com> <mailman.419.1462493404.32212.python-list@python.org> <5dd5db3e-ffa9-4c7b-9385-dc20f85dd45b@googlegroups.com>
Xref csiph.com comp.lang.python:108246

Show key headers only | View raw


On Fri, May 6, 2016 at 9:49 AM,  <mymyxin@gmail.com> wrote:
>
> In your example you used a base class
> and ICONINFO well as ICONINFOEX inherit it.
> As the members of ICONINFO are part of ICONINFOEX
> couldn't we do something like
>
> class ICONINFO_BASE(ctypes.Structure):
>     def __del__(self, ):
>         if self.hbmMask:
>             gdi32.DeleteObject(self.hbmMask)
>             self.hbmMask = None
>         if self.hbmColor:
>             gdi32.DeleteObject(self.hbmColor)
>             self.hbmColor = None
>
> class ICONINFO(ICONINFO_BASE):
>     _fields_ = (('fIcon',    wintypes.BOOL),
>                 ('xHotspot', wintypes.DWORD),
>                 ('yHotspot', wintypes.DWORD),
>                 ('hbmMask',  wintypes.HBITMAP),
>                 ('hbmColor', wintypes.HBITMAP))
>
> class ICONINFOEX(ICONINFO):
>     _fields_ = (('cbSize',    wintypes.DWORD),
>                 # ('fIcon',     wintypes.BOOL),
>                 # ('xHotspot',  wintypes.DWORD),
>                 # ('yHotspot',  wintypes.DWORD),
>                 # ('hbmMask',   wintypes.HBITMAP),
>                 # ('hbmColor',  wintypes.HBITMAP),
>                 ('wResID',    wintypes.WORD),
>                 ('szModName', wintypes.WCHAR * MAX_PATH),
>                 ('szResName', wintypes.WCHAR * MAX_PATH))

In this case, cbSize field will be offset after hbmColor:

    >>> ICONINFOEX.hbmColor.offset
    24
    >>> ICONINFOEX.cbSize.offset
    32

A struct subclass appends its fields to the base class fields. In
theory, you can do this in some cases, but in practice I don't
recommend it (see below).

For example, look at SHARE_INFO_0 [1], SHARE_INFO_1 [2], and
SHARE_INFO_2 [3], which are used to query different levels of
information about network shares.

[1]: https://msdn.microsoft.com/en-us/library/bb525402
[2]: https://msdn.microsoft.com/en-us/library/bb525407
[3]: https://msdn.microsoft.com/en-us/library/bb525408

It can help to maintain a consistent type hierarchy, such as in the
following answer that I wrote to list network shares on Windows:

http://stackoverflow.com/a/36848031/205580

When ctypes checks the type of a pointer argument, it first checks
whether its _type_ is a subclass of the _type_ of the corresponding
pointer type in argtypes. If not, it falls back on checking whether
the pointer argument itself is an instance of the argtypes pointer
type. Similarly, for a byref() argument it checks whether the referent
is an instance of the _type_ of the argtypes pointer type. Maintaining
a consistent type hierarchy provides type safety without having to
tediously cast pointers.

However, I don't recommend subclassing to append _fields_ because it
has a bug. The code that updates the StgDictObject (i.e. the subclass
of dict used by ctypes types for FFI storgage info) for structs and
union types doesn't doesn't properly initialize the ffi_type elements
array. The length field of the stgdict needs to be the total number of
fields, inclusive of all base classes, in order to copy the entire
ffi_type elements array from the base class. However, storing the
total length in the stgdict's length field would require rewriting the
way an instance of a struct is recursively initialized over the base
classes.

This bug affects passing structs by value. This isn't common (passing
unions by value isn't even supported), so I haven't bothered to submit
a patch for this. Here's an example crash on 64-bit Linux:

test.c:

    #include <stdio.h>

    typedef struct _data_t {
        int x, y, z;
    } data_t;

    int test(data_t d) {
        printf("%d, %d, %d\n", d.x, d.y, d.z);
        return 0;
    }

test.py:

    from ctypes import *

    lib = CDLL('./test.so')

    class A(Structure):
        _fields_ = (('a', c_int), ('b', c_int), ('c', c_int),)

    class B(Structure):
        _fields_ = (('a', c_int),)
    class C(B):
        _fields_ = (('b', c_int),)
    class D(C):
        _fields_ = (('c', c_int),)

    print('test A')
    lib.test(A(42, 84, 168))

    print('test D')
    lib.test(D(42, 84, 168))

output:
    test A
    42, 84, 168
    test D
    Aborted

Back to comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

python, ctypes and GetIconInfo issue mymyxin@gmail.com - 2016-05-05 13:47 -0700
  Re: python, ctypes and GetIconInfo issue eryk sun <eryksun@gmail.com> - 2016-05-05 19:09 -0500
    Re: python, ctypes and GetIconInfo issue mymyxin@gmail.com - 2016-05-06 06:36 -0700
      Re: python, ctypes and GetIconInfo issue eryk sun <eryksun@gmail.com> - 2016-05-06 18:38 -0500
    Re: python, ctypes and GetIconInfo issue mymyxin@gmail.com - 2016-05-06 07:49 -0700
      Re: python, ctypes and GetIconInfo issue eryk sun <eryksun@gmail.com> - 2016-05-06 18:39 -0500
        Re: python, ctypes and GetIconInfo issue mymyxin@gmail.com - 2016-05-07 14:58 -0700

csiph-web