从只知道内存地址的 Swift 调用 C 函数

Call C function from Swift knowing only memory address

我在 C 中有一个非常简单的函数,它的指针被传递到 Swift。

void callback() {
    NSLog(@"such pointer…");
}

如何在 Swift 中仅使用 指针调用它?这 NOT 关于简单地调用它——直接调用时它工作正常。尝试了以下和不同的签名转换变体,但它总是崩溃:

let pointer: UnsafePointer<@convention(c)() -> ()> = UnsafePointer(bitPattern: …)
let callback: @convention(c)() -> () = pointer.memory
Swift.print(callback) // (Function)
callback() // Handling crash with signal 11...

尝试用 typedef void(*Callback)(); 定义 Callback 类型 – 同样的事情:

let pointer: UnsafePointer<Callback> = UnsafePointer(bitPattern: …)
let callback: Callback = pointer.memory
Swift.print(callback) // (Function)
callback() // Handling crash with signal 11...

为了检查它是否确实有效并指向正确的地址,我有另一个 Objective-C 函数,当使用回调指针从 Swift 调用时,它按预期工作。

void invokeCallback(uintptr_t callback) {
    ((void (*)()) callback)(); // such pointer…
}

中相同的方法应该适用于此。

Swift 3 的示例(假设 funcPtr 是一个 UnsafeRawPointer 包含函数的地址):

// Define function type:
typealias callbackFunc = @convention(c) () -> Void

// Convert pointer to function type:
let callback = unsafeBitCast(funcPtr, to: callbackFunc.self)

// Call function:
callback()

当然类型别名必须与实际的函数签名匹配, 函数必须是 "pure" C 函数(不是 Objective-C 方法)。