您可以使用AnyObject
函数调用获取unsafeAdressOf(object:AnyObject) -> UnsafePointer<void>
的地址,但如何获取函数的地址?例如
func foo(){print("hi")}
print(unsafeAdressOf(foo))
不起作用
答案 0 :(得分:0)
不同的方法分派有不同的方法来获取Swift的函数指针。
这里是获取类的实例vtable方法指针的示例。
public func swift_getClassInstanceMethod(_ objc_class: AnyClass, methodIndex offset: Int) -> UnsafeMutablePointer<UnsafeMutableRawPointer>? {
let classPointer = Unmanaged.passUnretained(objc_class as AnyObject).toOpaque()
guard let outCount = malloc(MemoryLayout<UInt32>.size)?.assumingMemoryBound(to: UInt32.self) else { return nil }
defer {
free(outCount)
}
let _ = class_copyIvarList(objc_class, outCount)
let cachePointer = classPointer.advanced(by: 0x50 + 32*Int(outCount.pointee))
return cachePointer.advanced(by: offset*MemoryLayout<UnsafeMutableRawPointer>.size).assumingMemoryBound(to: UnsafeMutableRawPointer.self)
}
class B {
var a: Int = 1
var b: String?
// vtable: 0
init() {
}
// vtable: 1
func bTest() {
print("B test")
}
}
let B_bTest_pointer = swift_getClassInstanceMethod(B.self, methodIndex: 1)
另一种间接获取方法指针的方法。
typealias NewSwiftNSLog = @convention(thin) (_ format: String, _ args: CVarArg...) -> Void
func newNSLog(_ format: String, _ args: CVarArg...) {
print("hello world")
}
let nslog: NewSwiftNSLog = newNSLog
let nslogPointer = unsafeBitCast(nslog, to: UnsafeMutableRawPointer.self)
nslogPointer不是newNSLog函数指针,但是nslogPointer将调用newNSLog方法。