0

Pardon the confusing title but I am doing something truly cursed.

I have a large project written in Python that I want to write a GUI in Swift for. I'm able to use PythonKit to call my Python code from Swift just fine.

The only problem is that the Python program deals with laying out the UI elements since they form a directed graph and the layout algorithm is non-trivial.

The layout algorithm needs to know the size of each node in the graph to deal with overlapping nodes, but only the GUI knows what the rendered size of each node will be.

Therefore, I want to pass a callback written in Swift to the layout function that is written in Python.

I've pared down the code to be able to minimally reproduce the behavior.

let nodeSizeFn: @convention(c) (UnsafeMutableRawPointer?) -> UnsafeMutableRawPointer? = { _ in
    return PyInt_FromLong(30)
}

let nodeSizeFnPtr = unsafeBitCast(nodeSizeFn, to: UnsafeMutableRawPointer.self)
let nodeSizeFnAddr = UInt(bitPattern: nodeSizeFnPtr)

private let ctypes = Python.import("ctypes")
let sizefn = ctypes.CFUNCTYPE(ctypes.py_object)(nodeSizeFnAddr)

let (xs, ys, ws, hs) = graph.layout(sizefn).tuple4

This code segfaults in the call to PyInt_FromLong in the callback. From using LLDB, it seems that the SMALL_INT singleton/global object/static object (in CPython parlance) is null in the callback. I'm not sure how this is possible since PythonKit calls Py_Initialize and a similar call to PyInt_FromLong outside of the callback works fine.

Any and all help is appreciated. Thank you.

5
  • 1
    Post a minimal reproducible example. Anyway, you are misunderstanding the ctypes.CFUNCTYPE(). See Callback functions. Also why are you using the ctypes, instead of the PythonFunction API? See this. Commented Dec 4, 2023 at 9:52
  • I see now that I was misunderstanding CFUNCTYPE. I also somehow missed PythonFunction, thanks for pointing me to it. It's what I was looking for. I was using ctypes because I couldn't figure out how to create a Python callable from a function pointer. Anyways, if you want the points, you can post your comment as an answer Commented Dec 4, 2023 at 13:48
  • Why not answer your own question? Commented Dec 5, 2023 at 0:59
  • 1
    @relent95 Likely so that he can give you the credit and reward your insight. Commented Dec 5, 2023 at 1:48
  • @genghiskhan, you can have my credit. Commented Dec 5, 2023 at 2:04

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.