You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在大型Fortran程序中调用Julia函数?

高效实现Fortran调用Julia黑盒函数的方案

方案一:基于Julia C API + PackageCompiler.jl 生成共享库

这是最直接高效的方式,适配依赖复杂包的Julia函数,步骤如下:

1. 编写Julia端的C兼容接口

为你的output函数编写C可调用包装器,处理数组传递(Julia和Fortran均为列优先存储,可直接匹配,无需转置):

using PackageCompiler

# 你的黑盒函数(示例)
function output(x::Vector{Float64})::Vector{Float64}
    return x .* 2.0
end

# C兼容包装函数,用@ccallable宏导出
@ccallable function julia_output(x_ptr::Ptr{Cdouble}, x_len::Cint, out_ptr::Ptr{Cdouble})::Cvoid
    x = unsafe_wrap(Array, x_ptr, x_len; own=false)
    result = output(x)
    unsafe_copyto!(out_ptr, result, length(result))
end

# 生成包含Julia运行时和目标函数的共享库
create_library(".", "libjulia_output";
    functions=[julia_output],
    precompile_execution_file="precompile.jl", # 可选,预编译加速首次调用
    lib_name="libjulia_output",
    compiler_options=Dict(:optimize => 3)
)

注:若函数返回数组长度固定,建议在接口中明确;若长度可变,需额外向Fortran返回长度值。

2. Fortran端调用共享库

编写Fortran代码,通过bind(C)声明接口,调用生成的共享库:

program call_julia
    use, intrinsic :: iso_c_binding
    implicit none

    ! 声明C接口
    interface
        subroutine julia_output(x_ptr, x_len, out_ptr) bind(C, name='julia_output')
            import :: c_double, c_int, c_ptr
            type(c_ptr), value :: x_ptr, out_ptr
            integer(c_int), value :: x_len
        end subroutine julia_output
    end interface

    integer, parameter :: N = 5
    real(c_double) :: x(N), out(N)
    type(c_ptr) :: x_ptr, out_ptr

    ! 初始化输入
    x = [1.0d0, 2.0d0, 3.0d0, 4.0d0, 5.0d0]
    x_ptr = c_loc(x)
    out_ptr = c_loc(out)

    ! 调用Julia函数
    call julia_output(x_ptr, int(N, c_int), out_ptr)

    ! 输出结果
    print *, "Result from Julia: ", out

end program call_julia

3. 编译运行

编译Fortran程序时链接生成的共享库:

gfortran call_julia.f90 -o call_julia -L./ -ljulia_output -Wl,-rpath./

运行时需确保Julia共享库路径可被识别(若PackageCompiler生成的库依赖系统Julia库,需设置LD_LIBRARY_PATH)。

方案二:共享内存+信号量的高效IPC(备选)

若不想处理编译链接的复杂性,可通过共享内存实现进程间高效数据传递,避免文件IO的开销:

  • Julia端启动守护进程,监听共享内存中的输入数据,计算后写入结果区域,用信号量同步。
  • Fortran端负责写入输入到共享内存,发送信号量通知Julia,等待计算完成后读取结果。
    该方式延迟远低于文件读写,但实现复杂度高于共享库,适合快速原型验证。

为什么StaticCompiler.jl不适合你的场景

StaticCompiler.jl仅支持静态编译纯Julia函数,无法处理依赖复杂包(如用到全局状态、GC、外部C库的包)的场景,因此会出现未定义符号问题——这些符号属于Julia运行时或依赖包的动态链接部分,静态编译无法包含。而PackageCompiler.jl是将Julia运行时和你的函数打包成动态库,可适配所有依赖场景。

内容的提问来源于stack exchange,提问作者Itsnotme

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 16:22:18