首页 > 解决方案 > 导出已编译的 .dll 或 .so 文件以用于其他语言时,“初始化 Julia 运行时”是什么意思?

问题描述

我正在尝试从 Julia 编译一个可用的 .dll 文件以在 Python 中使用,因为我已经在 Python 中编写了一个大型 GUI,并且需要完成一些快速优化工作。通常我只会调用 PyJulia 或一些“实时”调用,但是这个程序需要编译才能在我的研究团队中分发,所以我最终得到的任何解决方案都需要能够独立运行(实际上没有安装 Julia 或 Python )。

现在我可以通过 PackageCompiler.jl 创建 .dll 文件,这是我从之前关于 StackOverflow 的帖子中学到的,但是当尝试通过以下代码在 Python 中运行这些文件时

Julia 模拟包


module JuliaFunctions
    # Pkg.add("BlackBoxOptim")
    Base.@ccallable function my_main_function(x::Cfloat,y::Cfloat)::Cfloat
        z = 0
        for i in 1:x
            z += i ^ y
        end
        return z
    end
    # function julia_main()
    #     print("Hello from a compiled executable!")
    # end
    export my_main_function

end  # module

使用 PackageCompiler 的 Julia 脚本

# using PackageCompiler
using Pkg
# Pkg.develop(path="JuliaFunctions")  # This is how you add a local package
# include("JuliaFunctions/src/JuliaFunctions.jl")  # this is how you add a local module
using PackageCompiler

# Pkg.add(path="JuliaFunctions")
@time create_sysimage(:JuliaFunctions, sysimage_path="JuliaFunctions.dll")

尝试在 Python 的 CTypes 中使用生成的 .dll

import ctypes
from ctypes.util import find_library
from ctypes import *

path = os.path.dirname(os.path.realpath(__file__)) + '\\JuliaFunctions.dll'

# _lib = cdll.LoadLibrary(ctypes.util.find_library(path))  # same error
# hllDll = ctypes.WinDLL(path, winmode=0)  # same error
with os.add_dll_directory(os.path.dirname(os.path.realpath(__file__))):
    _lib = ctypes.CDLL(path, winmode=0)

我明白了 OSError: [WinError 127] The specified procedure could not be found

以我目前的理解,这意味着 CTypes 找到了 dll 并导入了它,但没有找到.. 什么?我还没有完全掌握它的行为方式。

我已经通过Nirsoft 的 DLL Export Viewermy_main_function验证了该函数已导出到 .dll 文件中。来自之前类似问题的用户已经注意到,这个 sysimage 已经是可调用的并且应该可以工作,但他们总是在最后添加一些类似“请注意,您通常还需要初始化 Julia 运行时”的内容。

这是什么意思?这甚至可以独立于 Julia 安装完成吗?PackageCompiler 中的开发文档提到了这一点,但是他们只是提到 julia_main 自动包含在 .dll 文件中并被称为一种启动点。此函数也被正确导出到上述代码创建的 .dll 文件中。下面是 Nirsoft 导出查看器输出的图像以供参考。

Nirsoft .dll 导出查看器结果

编辑 1 莫名其妙地,我在另一台机器上重建了这个 .dll 并取得了进展。现在,dll 已正确导入。我还不确定为什么这适用于新的 Julia install + Python venv,但我将在另一个上重新安装它们,如果有任何变化,我会更新它。对于遇到这种情况的任何人,还请注意,您需要指定预期的输出,无论它可能是什么。在我的情况下,这是通过添加(在导入之后)完成的:

_lib.testmethod1.restype = c_double  # switched from Cfloat earlier, a lot has changed.
_lib.testmethod1.argtypes = [c_double, c_double]   # (defined by ctypes)

当前的错误现在是OSError: exception: access violation writing 0x0000000000000024在尝试实际使用该函数时,该函数特定于 Python。对此的任何帮助也将不胜感激。

标签: pythondlljuliactypespackagecompiler.jl

解决方案


推荐阅读