Skip to content

ctypes automatic byref failing on custom classes attributes #71990

Open

Description

@lepaperwan
BPO 27803
Nosy @amauryfa, @abalkin, @meadori, @eryksun, @lepaperwan

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = None
created_at = <Date 2016-08-19.18:11:36.954>
labels = ['ctypes', 'type-feature', '3.8', '3.9', '3.10']
title = 'ctypes automatic byref failing on custom classes attributes'
updated_at = <Date 2021-03-05.19:59:59.538>
user = 'https://github.com/lepaperwan'

bugs.python.org fields:

activity = <Date 2021-03-05.19:59:59.538>
actor = 'terry.reedy'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['ctypes']
creation = <Date 2016-08-19.18:11:36.954>
creator = 'lepaperwan'
dependencies = []
files = []
hgrepos = []
issue_num = 27803
keywords = []
message_count = 4.0
messages = ['273149', '273711', '273755', '273868']
nosy_count = 5.0
nosy_names = ['amaury.forgeotdarc', 'belopolsky', 'meador.inge', 'eryksun', 'lepaperwan']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'enhancement'
url = 'https://bugs.python.org/issue27803'
versions = ['Python 3.8', 'Python 3.9', 'Python 3.10']

Linked PRs

Activity

  1. lepaperwan commented on Aug 19, 2016

    lepaperwanmannequin
    MannequinAuthor

    When using a custom class to store a ctype value, passing that class as a function argument explicitly declared to be a pointer type fails to pass the _as_parameter_ class attribute as a pointer and instead raises a TypeError.

    For example:
    >>> from ctypes import *
    >>> from ctypes.wintypes import *
    >>>
    >>> class CustomPHKEY(object):
    ...     def __init__(self, value):
    ...             self._as_parameter_ = HKEY(value)
    ...
    >>>
    >>> function = windll.function
    >>> function.argtypes = [POINTER(HKEY)]
    >>> function.restype = LONG
    >>> result = CustomPHKEY(0)
    >>> function(result)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: expected LP_c_void_p instance instead of c_void_p

    Shouldn't ctypes apply the required byref() conversion automatically? Or is this behavior normal and automatic byref() only concerns native ctypes types?

    I only flagged Python 3.5 and Python 2.7 since they are the only ones I explicitly tested this on but I suspect other versions are affected.

  2. terryjreedy commented on Aug 26, 2016

    @terryjreedy
    Member

    I ran the the following, which I don't understand, and therefore don't what should happen, on Win 10, 3.6.0a3.

    from ctypes import *
    from ctypes.wintypes import *
    
    class CustomPHKEY(object):
        def __init__(self, value):
            self._as_parameter_ = HKEY(value)
    
    function = windll.function
    function.argtypes = [POINTER(HKEY)]
    function.restype = LONG
    result = CustomPHKEY(0)
    function(result)
    Traceback (most recent call last):
      File "F:\Python\mypy\tem.py", line 8, in <module>
        function = windll.function
      File "C:\Programs\Python36\lib\ctypes\__init__.py", line 417, in __getattr__
        dll = self._dlltype(name)
      File "C:\Programs\Python36\lib\ctypes\__init__.py", line 347, in __init__
        self._handle = _dlopen(self._name, mode)
    OSError: [WinError 126] The specified module could not be found
  3. eryksun commented on Aug 27, 2016

    @eryksun
    Contributor

    Terry, the provided example is incomplete and doesn't make sense as it stands. For better or worse, windll.dllname attempts to load WinDLL(dllname) and cache the resulting library on the windll loader. (The library in turn caches function pointers, which means this design is a problem waiting to happen, which has happened a few times with various projects conflicting with each other over windll.kernel32 function prototypes. I recommend using WinDLL instead.)

    I gather that Erwan wants ctypes.byref() and the implicit _byref that's called by PyCPointerType_from_param to be enhanced to support objects that define _as_parameter_. So I'm changing the issue type accordingly.

  4. added
    type-featureA feature request or enhancement
    and removed
    type-bugAn unexpected behavior, bug, or error
    on Aug 27, 2016
  5. lepaperwan commented on Aug 29, 2016

    lepaperwanmannequin
    MannequinAuthor

    I can confirm Eryk got what I meant. I didn't know if it was meant to work that way or if it was simply something that was overlooked so I thought I'd ask, I will look into the ctypes code to provide a patch sometime this week if I can.

    Terry, for a working example take the following (on a MS Windows):
    >>> from ctypes import *
    >>> from ctypes.wintypes import *
    >>>
    >>> class CustomPHKEY(object):
    ...     def __init__(self, value):
    ...             self._as_parameter_ = HKEY(value)
    ...
    >>>
    >>> function = ctypes.windll.advapi32.RegOpenKeyExW
    >>> function.argtypes = [HKEY, c_wchar_p, DWORD, DWORD, POINTER(HKEY)]
    >>> function.restype = LONG
    >>> result = CustomPHKEY(0)
    >>> function(0x80000002, 'SOFTWARE', 0, 0x20019, result)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    ctypes.ArgumentError: argument 5: <type 'exceptions.TypeError'>: expected LP_c_void_p instance instead of c_void_p
  6. transferred this issue fromon Apr 10, 2022
  7. added
    3.16new features, bugs and security fixes
    and removed on Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    3.16new features, bugs and security fixestopic-ctypestype-featureA feature request or enhancement

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions