I was successfully using dlsym to dynamically load and invoke functions at runtime. Now I need to load constants and for some reason unsafeBitCast fails on me, whereas assumingMemoryBound works. However, using assumingMemoryBound with a function somehow messes with it and it crashes during the invocation.
unsafeBitCast fails with constant:
import Foundation
internal typealias F = @convention(c) (_ alloc: CFAllocator?, _ cStr: UnsafePointer<UInt8>, _ encoding: CFStringEncoding) -> CFString?
func load<T>(_ name: String) -> T {
unsafeBitCast(dlsym(dlopen(nil, RTLD_NOW), name), to: T.self)
}
print(load("CFStringCreateWithCString") as F) // (Function)
print((load("CFStringCreateWithCString") as F)(nil, [102, 111, 111, 0], CFStringBuiltInEncodings.UTF8.rawValue)!) // foo
print(load("kCFErrorLocalizedFailureKey") as CFString) // EXC_BAD_ACCESS
assumingMemoryBound fails with invocation:
import Foundation
internal typealias F = @convention(c) (_ alloc: CFAllocator?, _ cStr: UnsafePointer<UInt8>, _ encoding: CFStringEncoding) -> CFString?
func load<T>(_ name: String) -> T {
dlsym(dlopen(nil, RTLD_NOW), name).assumingMemoryBound(to: T.self).pointee
}
print(load("kCFErrorLocalizedFailureKey") as CFString) // NSLocalizedFailure
print(load("CFStringCreateWithCString") as F) // (Function)
print((load("CFStringCreateWithCString") as F)(nil, [102, 111, 111, 0], CFStringBuiltInEncodings.UTF8.rawValue)!) // EXC_BAD_ACCESS
Can anybody explain what's going on? Is there a way to load all kinds of symbols with one declaration?