# Understanding calling conventions passing closure from Swift to C++ and calling it from C++

**URL:** <https://forums.swift.org/t/understanding-calling-conventions-passing-closure-from-swift-to-c-and-calling-it-from-c/79995>\
**Category:** Using Swift\
**Tags:** cxx-interop\
**Created:** [May 19, 2025, 11:56pm UTC](https://forums.swift.org/t/understanding-calling-conventions-passing-closure-from-swift-to-c-and-calling-it-from-c/79995 "2025-05-19T23:56:16Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![jamesmoschou](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jamesmoschou/32/40906_2.png) [@jamesmoschou](https://forums.swift.org/u/jamesmoschou)\
**Post date:** [May 19, 2025, 11:56pm UTC](https://forums.swift.org/t/understanding-calling-conventions-passing-closure-from-swift-to-c-and-calling-it-from-c/79995/1 "2025-05-19T23:56:16Z")

</div>

Hello,

I have a Swift function like

```swift
extension Anything {
  @_extern(c, "XYZPerformWithCallback")
  static func performWithCallback(_ callback: () -> Void)
}

```

And in C++ it is implemented like this:

```c++
// XYZ_SWIFT_CC(swift) is the Swift calling convention.
#if __has_attribute(swiftcall)
#define XYZ_SWIFT_CC_swift __attribute__ ((swiftcall))
#define XYZ_SWIFT_CONTEXT __attribute__ ((swift_context))
#else
#define XYZ_SWIFT_CC_swift
#define XYZ_SWIFT_CONTEXT
#endif

void XYZPerformWithCallback(
  void (*callback)(const void *context XYZ_SWIFT_CONTEXT) XYZ_SWIFT_CC(swift),
  const void *context
) {
  callback(context);
}

```

This works perfectly fine. The Swift code calls the C++ function. The C++ function calls the callback and returns control to Swift.

But when I change the Swift function to be a global function instead of a static method, the C++ code crashes when trying to invoke the callback.

My question is, what is the difference? How can I understand this?

Is the presence of the `Self` variable changing what gets mapped to what register? If anything, I would expect the global function to work and the static method not to.

---

<div class="post-metadata">

**Author:** ![Joe\_Groff](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/joe_groff/32/1929_2.png) [@Joe\_Groff](https://forums.swift.org/u/Joe_Groff)\
**Post date:** [May 20, 2025, 12:53am UTC](https://forums.swift.org/t/understanding-calling-conventions-passing-closure-from-swift-to-c-and-calling-it-from-c/79995/2 "2025-05-20T00:53:57Z")

</div>

`@_extern(c)` is an unsupported feature, and I would recommend against using it. The mapping of Swift calling conventions to nonstandard Clang attributes like ` __attribute__ ((swiftcall))` is also not necessarily stable or reliable. If you want to implement something in C++, I would define it in C++, and then declare it in a C++ header file and import it into Swift that way.

---

<div class="post-metadata">

**Author:** ![jamesmoschou](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jamesmoschou/32/40906_2.png) [@jamesmoschou](https://forums.swift.org/u/jamesmoschou)\
**Post date:** [May 20, 2025, 9:46am UTC](https://forums.swift.org/t/understanding-calling-conventions-passing-closure-from-swift-to-c-and-calling-it-from-c/79995/3 "2025-05-20T09:46:33Z")

</div>

I am doing it this way because it lets me pass closures with captured variables.

I am assuming that this is plain unsupported then.
