GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-152433: Make ctypes callbacks work on Windows UWP builds by thexai · Pull Request #161539 · python/cpython

Conversation

@thexai

@thexai thexai commented Nov 7, 2026

Copy link
Copy Markdown
Contributor

This PR implements parts missing in #154700 for full ctypes functionality in UWP:

UWP does not allow memory to be writable and executable at the same time. Allocate each closure in its own PAGE_READWRITE page, then switch it to PAGE_EXECUTE_READ with VirtualProtectFromApp() and flush the instruction cache once ffi_prep_closure_loc() has written it.

Full tested in various ways:

  • Regular test_ctypes pass in Windows x64 Desktop.
  • Changed !defined(MS_WINDOWS_DESKTOP) to defined(MS_WINDOWS_DESKTOP) and test_ctypes also is pass using UWP code path in Desktop (needs be linked with WindowsApp.lib to use VirtualProtectFromApp).
  • Tested with specific ctypes callbacks test code:
"""Check that ctypes callbacks can be executed (gh-152433, Windows UWP).

Before the fix, the closure trampoline lives in PAGE_READWRITE memory, so
the first call into it raises:
    OSError: exception: access violation executing 0x...
After the fix, every check prints OK.
"""
import ctypes
import gc
import sys

INTFUNC = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int)
CMPFUNC = ctypes.CFUNCTYPE(ctypes.c_int,
                           ctypes.POINTER(ctypes.c_int),
                           ctypes.POINTER(ctypes.c_int))


def check(name, func):
    try:
        func()
    except Exception as exc:
        print(f"FAIL {name}: {type(exc).__name__}: {exc}")
        return False
    print(f"OK   {name}")
    return True


def call_through_pointer():
    # Calling the callback via its raw address forces execution of the
    # generated trampoline; no external DLL is needed.
    cb = INTFUNC(lambda x: x * 2)
    func = ctypes.cast(cb, INTFUNC)
    assert func(21) == 42, func(21)


def many_callbacks():
    # Allocate and free many closures to exercise the allocator.
    for i in range(1000):
        cb = INTFUNC(lambda x, i=i: x + i)
        assert ctypes.cast(cb, INTFUNC)(1) == i + 1
    gc.collect()


def qsort_from_crt():
    # C code calling back into Python.
    try:
        crt = ctypes.CDLL("ucrtbase")
    except OSError as exc:
        print(f"SKIP qsort (cannot load ucrtbase: {exc})")
        return
    values = (ctypes.c_int * 5)(5, 1, 4, 2, 3)
    cmp = CMPFUNC(lambda a, b: a[0] - b[0])
    crt.qsort(values, len(values), ctypes.sizeof(ctypes.c_int), cmp)
    assert list(values) == [1, 2, 3, 4, 5], list(values)


results = [
    check("call callback through pointer", call_through_pointer),
    check("create/free 1000 callbacks", many_callbacks),
    check("qsort with Python comparator", qsort_from_crt),
]

print("PASSED" if all(results) else "FAILED")
  • The test code adapted to Kodi Python add-on and tested in Xbox Series S (backported to Python 3.14.10):
screenshot00000

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@bedevere-app bedevere-app Bot added awaiting review type-feature A feature request or enhancement labels Nov 7, 2026
@bedevere-app bedevere-app Bot mentioned this pull request Nov 7, 2026
Windows: improve compatibility to build for UWP / Xbox #152433
Open
@thexai @claude
pythongh-152433: Make ctypes callbacks work on Windows UWP builds
de86e82
UWP does not allow memory to be writable and executable at the same
time. Allocate each closure in its own PAGE_READWRITE page, then switch
it to PAGE_EXECUTE_READ with VirtualProtectFromApp() and flush the
instruction cache once ffi_prep_closure_loc() has written it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@thexai
thexai force-pushed the gh-152433-uwp-ctypes-callbacks branch from 5680317 to de86e82 Compare November 7, 2026 08:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

awaiting review type-feature A feature request or enhancement

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@thexai
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.