Open mrousavy opened 2 weeks ago
Okay I just found out that the offending piece of code is the self.implementation.someCallback =
part.
If I just capture the std::function
locally, it works ✅:
set {
let captured: (_ num: Double) -> Void = { num in
newValue(num)
}
}
But as soon as I capture it and assign it to another property (in my case, implementation
is a protocol), it fails ❌:
set {
let captured: (_ num: Double) -> Void = { num in
newValue(num)
}
self.implementation.someCallback = { (num: Double) -> Void in
captured(num)
}
}
With this error:
- Global is external, but doesn't have external or weak linkage!
Are there any workarounds for this?
I just explicitly wrapped the std::function
in a shared_ptr
, and now it works:
let shared = bridge.share_Func_void_double(callback)
self.implementation.someCallback = { (value: Double) -> Void in
shared.pointee.callAsFunction(value)
})
This is a bit hacky and obviously introduces some overhead, so I would prefer to just use the std::function
directly. But hey, at least it builds now!
Description
I have a C++
std::function<void(double)>
(astd::function
with arguments) which I want to wrap in a nice Swift closure ((Double) -> Void
), to be able to call it later.The C++
std::function
has some captured state, in my case ashared_ptr
, but it is still copyable:My Swift property then wraps this
std::function
as a Swift closure:While this works with an
std::function
without arguments (std::function<void()>
), it crashes the compiler when using astd::function
with arguments (std::function<void(double)>
)!Reproduction
Stack dump
Expected behavior
I expect the Swift closure to properly capture the
std::function
, so I can call it later. After all, it is a copyablestd::function
.Environment
swift-driver version: 1.90.11.1 Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4) Target: arm64-apple-macosx14.0
Additional information
No response