由于 dlopen 返回 nil,PythonKit 在启动时崩溃

Ani*_*ssa 5 python swift swift-pythonkit

我正在尝试在我的 Swift 项目中使用 PythonKit 来使用一些 Python 代码。为此,我下载了新的 Xcode 11 以将 PythonKit 添加为 Swift 包。添加带有 Swift Package 的 PythonKit 后,我​​在这里就有了这些项目依赖项。

项目依赖关系

我想在应用程序启动时使用 Python 代码,因此我将对 Python 代码的调用放在我的应用程序委托中的应用程序函数中。

import UIKit
import PythonKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        let sys = Python.import("sys")
        print("Python Version: \(sys.version)")
        sys.path.append("/Users/me/Documents/MyProject/MyPackage/my_python_main_file")
        let pythonAPI = Python.import("my_python_main_file")
        pythonAPI.main_function.call()

        return true
    }
Run Code Online (Sandbox Code Playgroud)

运行我的项目后,出现以下错误:

致命错误:找不到 Python 库。使用 Python 库的路径设置 PYTHON_LIBRARY 环境变量。

我尝试使用断点遵循不同的步骤,以了解代码实际崩溃的位置。以下是 PythonKit 经历的不同阶段:

它进入 PythonLibraryinit()并产生错误:

guard let pythonLibraryHandle = PythonLibrary.loadPythonLibrary() else {
      fatalError("""
        Python library not found. Set the \(Environment.library.key) \
        environment variable with the path to a Python library.
        """)
    }
Run Code Online (Sandbox Code Playgroud)

经查,是因为函数dlopen内部调用的原因loadPythonLibrary

static func loadPythonLibrary(at path: String) -> UnsafeMutableRawPointer? {
    log("Trying to load library at '\(path)'...")
    #if canImport(Darwin) || canImport(Glibc)
    // Must be RTLD_GLOBAL because subsequent .so files from the imported python
    // modules may depend on this .so file.
    let pythonLibraryHandle = dlopen(path, RTLD_LAZY | RTLD_GLOBAL)
    #elseif os(Windows)
    let pythonLibraryHandle = UnsafeMutableRawPointer(LoadLibraryA(path))
    #endif

    if pythonLibraryHandle != nil {
      log("Library at '\(path)' was sucessfully loaded.")
    }
    return pythonLibraryHandle
  }
Run Code Online (Sandbox Code Playgroud)

这个函数返回nil,这是由于dlopen函数返回nil

但是,我检查了作为参数给出的路径loadPythonLibrary(at : path),它似乎是正确的(在终端中我尝试cd对以下路径执行操作并且它有效):

/usr/local/Frameworks/Python.framework/Versions/2.7/Python

我在代码中使用 Python 2.7。

你知道我为什么dlopen会回来吗?nil

cah*_*ahn 2

您现在可以使用我的 PythonKit 分支(https://github.com/kewlbear/PythonKit )来完成此操作。这个包依赖于我的另一个包https://github.com/kewlbear/Python-iOS。最终 Python 将嵌入到应用程序中。目前使用Python 3.8。