iby
(Ian Bytchek)
1
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?
iby
(Ian Bytchek)
2
@eskimo, @NeoNacho, @mayoff, you guys posted some great answers on these matter. May I kindly ask for your input?
Joe_Groff
(Joe Groff)
3
A function symbol generally resolves to the entry point of the function, which in C would be a function pointer type, or in Swift a @convention(c) function type. A data symbol generally resolves to the address of the data, not the data itself, so you probably want to resolve kCFErrorLocalizedFailureKey as an UnsafePointer<CFString> and load the CFString from the pointer.
1 Like
iby
(Ian Bytchek)
4
Argh! Brilliant! Thanks you very much!
You say generally. Is that the rule or might there be exceptions? Are there any other things to keep in mind when dlsym'ing things?
Joe_Groff
(Joe Groff)
5
Well, there are also "absolute symbols" whose value can directly encode a pointer-sized integer value, but you're unlikely to encounter them in practice.
2 Likes