如何使用FFI将二维矢量从Rust传递到Fortran?

如何使用FFI将二维矢量从Rust传递到Fortran?,rust,fortran,ffi,Rust,Fortran,Ffi,我试图将2D f64向量(Vec)从Rust传递到Fortran函数。我一直在使用1D向量和其他Fortran函数,使用.as_mut_ptr() 我不完全确定如何为类似的东西发布一个最简单的工作示例,但现在我们开始: extern "C" { fn fortran1_( vector: *mut f64, length1: *const uint32_t ); fn fortran2_( vector

我试图将2D f64向量(Vec)从Rust传递到Fortran函数。我一直在使用1D向量和其他Fortran函数,使用.as_mut_ptr()

我不完全确定如何为类似的东西发布一个最简单的工作示例,但现在我们开始:

extern "C" {
    fn fortran1_(
        vector: *mut f64,
        length1: *const uint32_t
    );

    fn fortran2_(
        vector: *mut f64, 
        length1: *const uint32_t, 
        length2: *const uint32_t
    );
}

pub fn fortran1(
    length1: u32
) -> Vec<f64>{
    let mut vector = vec![0_f64; length1];
    unsafe{
        fortran1_(
            vector.as_mut_ptr(),
            &length1)
    }
    return vector;
}

pub fn fortran2(
    length1: u32, 
    length2: u32
)-> Vec<Vec<f64>>{
    let mut vector = vec![vec![0_f64; length1]; length2];
    unsafe{
        fortran2_(vector.as_mut_ptr(), 
        &length1, 
        &length2)
    }
    return vector;
}
extern“C”{
fn fortran1_(
向量:*mut f64,
长度1:*施工单位32
);
fn fortran2_(
向量:*mut f64,
长度1:*施工单位32,
长度2:*施工单位32\t
);
}
福特兰1号酒店(
长度1:u32
)->Vec{
让mut vector=vec![0_f64;长度1];
不安全{
fortran1_(
vector.as_mut_ptr(),
&长度1)
}
返回向量;
}
福特兰2号酒店(
长度1:u32,
长度2:u32
)->Vec{
让mut vector=vec![vec![0_f64;长度1];长度2];
不安全{
fortran2(向量.as_mut_ptr(),
&长度1,
&长度(2)
}
返回向量;
}

谢谢

在rust
Vec
表示法和Fortran的标准数据模型之间存在大量不匹配

Fortran希望二维数组被放置在
f64
的一个连续切片中,但
Vec
将其每一行放在单独的堆分配中

Fortran索引是基于1的,但是
Vec
是基于0的

最好实现一个
struct Fortran2d{vec:vec,rows:usize,cols:usize,}
并在该模拟Fortran索引上实现方法。我想那是最不痛苦的

impl Fortran2d<T> {
    /// maps fortran style 2d index to internal vec index
    fn index(&self, c: usize, r: usize) -> usize {
        assert!(c > 0 && c <= self.cols);
        assert!(r > 0 && r <= self.rows);
        (c - 1) + (r - 1) * self.cols
   }
}
impl Fortran2d{
///将fortran样式的2d索引映射到内部vec索引
fn索引(&self,c:usize,r:usize)->usize{

断言!(c>0&&c 0&&r我强烈建议使用1D数组,并像处理多维数组一样处理它,或者使用.a
Vec
不在线存储其元素,这意味着虽然来自每个内部数组的数据是连续的,但内部数组彼此不连续。换句话说,您无法访问第二个向量通过索引或指针算法,因为没有一致的步幅模式。Nit:“Fortran索引是基于1的”…默认值是基于1的,但Fortran允许您使用任何想要的整数基。