# Foreign Callbacks via Raw Pointers

**URL:** <https://forums.swift.org/t/foreign-callbacks-via-raw-pointers/62932>\
**Category:** Using Swift\
**Created:** [February 3, 2023, 12:46pm UTC](https://forums.swift.org/t/foreign-callbacks-via-raw-pointers/62932 "2023-02-03T12:46:36Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Bogdanp](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bogdanp/32/28621_2.png) [@Bogdanp](https://forums.swift.org/u/Bogdanp)\
**Post date:** [February 3, 2023, 12:46pm UTC](https://forums.swift.org/t/foreign-callbacks-via-raw-pointers/62932/1 "2023-02-03T12:46:36Z")

</div>

I am embedding a dynamic programming language inside my Swift application. Said programming language's runtime runs in a background thread and my app normally communicates with it asynchronously via pipes. Now, I have a need for the programs written in that language to be able to occasionally execute Swift callbacks. So, I have the following mechanism for installing these callbacks:

```swift
public func installCallback(id: CallbackID, proc: @escaping (InputPort) -> Void) {
  callbacks[id] = proc
  let addr = Int(bitPattern: unsafeBitCast(callbackHandler, to: Optional<UnsafeRawPointer>.self)!)
  registerWithOtherLang(id, Int64(addr))
}

fileprivate typealias CallbackID = UInt64
fileprivate var callbacks = [CallbackID: (InputPort) -> Void]()
fileprivate let callbackHandler: @convention(c) (CallbackID, Int, UnsafePointer<CChar>) -> Void = ...

```

Where the `callbackHandler` procedure looks up a callback by its id when called from the other side and applies it to the data it receives (handler args 2 and 3 are a size and data, respectively). The `registerWithOtherLang` procedure instructs the other language's runtime to keep track of a foreign procedure (from its perspective) with the address of the callback handler.

This works reliably, but I'm new to Swift and I'm concerned I don't know what I don't know. Specifically, I wonder if `callbackHandler`'s address could change at runtime or if there are any other problems with this approach.

---

<div class="post-metadata">

**Author:** ![stuchlej](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/stuchlej/32/7751_2.png) [@stuchlej](https://forums.swift.org/u/stuchlej)\
**Post date:** [February 3, 2023, 12:58pm UTC](https://forums.swift.org/t/foreign-callbacks-via-raw-pointers/62932/2 "2023-02-03T12:58:52Z")

</div>

If you're looking for more information, I have [How do closures work (memory management)](https://forums.swift.org/t/how-do-closures-work-memory-management/47512) and maybe this post also lightly touches the topic [Dynamically loading a Swift `shared object` / `dylib`](https://forums.swift.org/t/dynamically-loading-a-swift-shared-object-dylib/62732) .

At the first glance I don't see anything wrong (albeit the callback casting seems a little clumsy to me). The context of those Swift closures never "leaves" the Swift environment - worst case scenario: those closures are never released by the dictionary that retains them.

My only concern would be, that if you're in multi-threaded environment, the access to the `callbacks` dictionary should be done in a safe manner.

---

<div class="post-metadata">

**Author:** ![Bogdanp](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/bogdanp/32/28621_2.png) [@Bogdanp](https://forums.swift.org/u/Bogdanp)\
**Post date:** [February 3, 2023, 1:04pm UTC](https://forums.swift.org/t/foreign-callbacks-via-raw-pointers/62932/3 "2023-02-03T13:04:07Z")

</div>

Thanks! I'll check out those threads. Good point about access to `callbacks`. I'm not too worried about retaining the closures perpetually since `installCallbacks` will only be used at most once or twice for the life time of the app and the closures themselves won't capture much.
