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

使用jlrs在Rust中创建Julia字符串数组并调用函数的问题

问题:使用jlrs在Rust中调用接收String数组的Julia函数

我正在用jlrs crate在Rust代码里调用Julia函数,现在需要调用一个接收Vector{String}类型参数的Julia函数,函数定义如下:

function create_temporals(ts::Vector{String}, ts_format="yyyy-mm-ddTHH:MM:SSzzzz")
    # ... 函数实现
end

我的Rust代码如下,但不知道怎么把Rust数据转换成Julia数组。试过用jlrs::data::managed::Array,但它需要ExtendedTarget参数,不知道怎么处理,也不清楚怎么把Rust数据传入Julia数组:

pub fn _call1<'target, 'data, T: Target<'target>>(
    target: T, 
    module: &str, 
    function: &str, 
    data1: Value<'_, 'data>
) -> JlrsResult<ValueResult<'target, 'data, T>> {
    unsafe {
        let res = Module::main(&target)
            .submodule(&target, module)?
            .as_managed()
            .function(&target, function)?
            .as_managed()
            .call1(target, data1);

        Ok(res)
    }
}
pub fn _temporals<T>(timestamps: &T) {
    let mut frame = StackFrame::new(); 
    let mut pending = unsafe { RuntimeBuilder::new().start().expect("Could not init Julia") };
    let mut julia = pending.instance(&mut frame);

    unsafe {
        let path = PathBuf::from("structures.jl");
        if path.exists() {
            julia.include(path).expect("Could not include file");
        } else {
            julia
                .include("src/Predicer/src/structures.jl")
                .expect("Could not include file");
        }
    }

    let _x = julia.scope(|mut frame| {
        
        let timestamps: Vec<String> = vec![
        "2023-06-20T10:30:00".to_string(),
        "2023-06-20T10:45:00".to_string(),
        "2023-06-20T11:00:00".to_string(),
    ];

    // Convert the Rust vector into a Julia array
    let temporals = Array::new(&mut frame, (3,));

        let module = "Structures"; 
        let function = "create_temporals"; 
        let _result_node = _call1(frame, module, function, temporals);
        Ok(()) 
        
    }).expect("result is an error");
}

解决方案

核心要点

要将Rust的Vec<String>转换为Julia的Vector{String},需要完成两步:创建对应类型的Julia空数组,再将每个Rust字符串转换为Julia字符串并填充到数组中。ExtendedTarget本质上就是&mut Frame,直接使用闭包内的frame即可满足要求。

修正后的代码

use jlrs::prelude::*;
use std::path::PathBuf;

pub fn _call1<'target, 'data, T: Target<'target>>(
    target: T, 
    module: &str, 
    function: &str, 
    data1: Value<'_, 'data>
) -> JlrsResult<ValueResult<'target, 'data, T>> {
    unsafe {
        let res = Module::main(&target)
            .submodule(&target, module)?
            .as_managed()
            .function(&target, function)?
            .as_managed()
            .call1(target, data1);

        Ok(res)
    }
}

pub fn _temporals<T>(_timestamps: &T) {
    let mut frame = StackFrame::new(); 
    let mut pending = unsafe { RuntimeBuilder::new().start().expect("Could not init Julia") };
    let mut julia = pending.instance(&mut frame);

    unsafe {
        let path = PathBuf::from("structures.jl");
        if path.exists() {
            julia.include(path).expect("Could not include file");
        } else {
            julia
                .include("src/Predicer/src/structures.jl")
                .expect("Could not include file");
        }
    }

    let _x = julia.scope(|mut frame| {
        let timestamps: Vec<String> = vec![
            "2023-06-20T10:30:00".to_string(),
            "2023-06-20T10:45:00".to_string(),
            "2023-06-20T11:00:00".to_string(),
        ];

        // 创建Julia的String类型数组,尺寸对应Rust向量长度
        let mut temporals = unsafe {
            Array::new::<JuliaString, _, _>(&mut frame, (timestamps.len(),))
                .expect("Failed to create Julia array")
        };

        // 遍历Rust字符串,转换为Julia字符串并填充到数组
        for (idx, s) in timestamps.into_iter().enumerate() {
            let julia_str = unsafe {
                JuliaString::new(&mut frame, s)
                    .expect("Failed to create Julia string")
            };
            unsafe {
                temporals.set(&mut frame, idx as isize, julia_str)
                    .expect("Failed to set element in array");
            }
        }

        let module = "Structures"; 
        let function = "create_temporals"; 
        // 调用函数,注意传递frame而非消耗它
        let _result_node = _call1(&mut frame, module, function, temporals.as_value());
        Ok(()) 
        
    }).expect("result is an error");
}

关键修正说明

  1. 数组创建:明确指定数组元素类型为JuliaString(对应Julia的String),尺寸使用Rust向量的长度而非硬编码的3,提升灵活性。
  2. 字符串转换与填充:通过JuliaString::new将每个RustString转换为Julia字符串,再用Array::set将元素写入数组对应位置。
  3. 函数调用参数:调用_call1时传递&mut frame作为Target,并通过as_value()将数组转换为Value类型参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 20:05:08