GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing github.com — gh-152433: Make ctypes callbacks work on Windows UWP builds by thexai · Pull Request #161539 · python/cpython Conversation
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 Full tested in various ways:
"""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")
Sorry, something went wrong. Uh oh!
There was an error while loading. Please reload this page. All reactionsUWP 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
force-pushed
the
gh-152433-uwp-ctypes-callbacks
branch
from
5680317 to
de86e82
Compare
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ReviewersNo reviewsUh oh!
There was an error while loading. Please reload this page. AssigneesNo one assignedLabelsProjectsMilestoneNo milestoneDevelopmentSuccessfully merging this pull request may close these issues. Uh oh!
There was an error while loading. Please reload this page. 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. |