gpt4 book ai didi

swift - 在运行时检查 Swift 中来自第三方框架的弱链接符号

转载 作者:搜寻专家 更新时间:2023-10-31 21:46:33 24 4
gpt4 key购买 nike

在 macOS 上,我使用了一个必须由用户安装的外部框架(用 C 编写)。在 Swift 中,我需要在运行时检查它是否存在,并且我不能使用 #available() 因为它用于与操作系统相关的功能,而且我正在尝试追踪外部框架。此外,NSClassFromString() 也没有用,因为它不是 Objective-C 框架。

我一直在努力了解如何复制 Objective-C 等价物来检查弱链接符号,例如:

if ( anExternalFunction == NULL ) {
// fail graciously
} else {
// do my thing
}

但在 Swift 中,这似乎行不通:编译器指出,由于 anExternalFunction 不是可选的,我将始终得到 != nil,这使“Swift 有意义”但对我一点帮助都没有。

我找到了两个解决方案,但它们让我的代码臭烘烘的,你不会相信:

选项 1,使用名为 isFrameworkAvailable() 的函数创建一个 Objective-C 文件,并从 Swift 调用

选项 2,实际使用以下 Swift 代码检查库:

let libHandle = dlopen("/Library/Frameworks/TheLib.framework/TheLib", RTLD_NOW)

if (libHandle != nil) {
if dlsym(libHandle, "anExternalFunction") != nil {
return true
}
}
return false

我一直无法让选项 2 与 RTLD_DEFAULT 一起很好地工作,因为出于某种原因,它在 dlfcn.h (-2) 中定义,但似乎没有在 Swift 中导入(就像该 header 中的所有负指针一样: RTLD_NEXT、RTLD_DEFAULT、RTLD_SELF、RTLD_MAIN_ONLY)。我发现了使它起作用的最丑陋的技巧:

if dlsym(unsafeBitCast(-2, to: UnsafeMutableRawPointer.self), "anExternalFunction") != nil {
// library installed
}

所以对于选项 2,我需要路径或 hack,我发现它特别难看(但它有效)并且选项 1 不是很“敏捷”并且对我来说没什么意义:这样做的正确方法是什么在 Swift 中?

编辑:澄清问题,更好地解释选项 2。

最佳答案

我找到了两种方法:

    1.
if let _ = dlopen("/Library/Frameworks/MyLibrary.framework/MyLibrary", RTLD_NOW) {
print("Can open my library")
}
    2.
#if canImport(MyLibrary)
print("Can import my library")
#endif

从可读性和类型安全的角度来看,第二种显然更好,但我不确定两者之间的权衡是什么。

关于swift - 在运行时检查 Swift 中来自第三方框架的弱链接符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47277795/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com