未明确引用`_gfortran_cpu_time_4'

时间:2016-05-16 08:54:46

标签: fortran rust ffi

我正在尝试从 Rust 调用 Fortran 函数,但我收到此错误:

query = ParseQuery.getQuery("TestObject");
query.whereContains("test", "test.png");
query.findInBackground(new FindCallback<ParseObject>() {
    @Override
    public void done(List<ParseObject> objects, ParseException e) {
        if (e == null) {
            objectId = objects.get(0).getObjectId();
            query.getInBackground(objectId, new GetCallback<ParseObject>() {
                @Override
                public void done(ParseObject object, ParseException e) {
                    if (e == null) {
                        object.deleteInBackground(new DeleteCallback() {
                            @Override
                            public void done(ParseException e) {
                                if (e == null) {
                                    Log.e("Delete", "SUCCESS");
                                } else {
                                    Log.e("Delete", e.getMessage());
                                }
                            }
                        });
                     } else {
                        Log.e("getInBackground", e.getMessage());
                     }
                }
            });
        } else {
            Log.e("findInBackground", e.getMessage());
        }
    }
});

我通过互联网搜索但无法找到解决方法。 Fortran代码是:

/src/timer.f:4: undefined reference to `_gfortran_cpu_time_4'

Rust绑定是:

subroutine timer(ttime)
  double precision ttime
  temp = sngl(ttime)
  call cpu_time(temp)
  ttime = dble(temp) 

  return
end

我不知道自己做错了什么。

1 个答案:

答案 0 :(得分:1)

正如评论者所说,你需要link to libgfortran

具体来说,在Rust世界中,您应该使用(或创建)详细说明相应链接步骤的*-sys package并公开基本API。然后在此基础上构建更高级别的抽象。

但是,我似乎不需要做任何事情:

<强> timer.f90

subroutine timer(ttime)
  double precision ttime
  temp = sngl(ttime)
  call cpu_time(temp)
  ttime = dble(temp) 

  return
end

<强> Cargo.toml

[package]
name = "woah"
version = "0.1.0"
authors = ["An Devloper <an.devloper@example.com>"]

build = "build.rs"

[dependencies]
libc = "*"

<强> build.rs

fn main() {
    println!("cargo:rustc-link-lib=dylib=timer");
    println!("cargo:rustc-link-search=native=/tmp/woah");
}

<强>的src / main.rs

extern crate libc;

use libc::{c_double};

extern "C" {
    pub fn timer_(d: *mut c_double);
}

fn main() {
    let mut value = 0.0;
    unsafe { timer_(&mut value); }
    println!("The value was: {}", value);
}

它通过

组合在一起
$ gfortran-4.2 -shared -o libtimer.dylib timer.f90
$ cargo run
The value was: 0.0037589999847114086

这似乎表明此共享库不需要libgfortranit's being automatically included

如果您改为创建静态库(并通过cargo:rustc-link-lib=dylib=timer适当地链接到它):

$ gfortran-4.2 -c -o timer.o timer.f90
$ ar cr libtimer.a *.o
$ cargo run
note: Undefined symbols for architecture x86_64:
  "__gfortran_cpu_time_4", referenced from:
      _timer_ in libtimer.a(timer.o)

在这种情况下,添加gfortran允许代码编译:

println!("cargo:rustc-link-lib=dylib=gfortran");

免责声明:我以前从未编译过Fortran,所以我很可能做了些傻事。