登录
首页 >  Golang >  Go问答

从 go 调用 fortran 库的最小示例

来源:stackoverflow

时间:2024-04-11 22:09:32 466浏览 收藏

一分耕耘,一分收获!既然都打开这篇《从 go 调用 fortran 库的最小示例》,就坚持看下去,学下去吧!本文主要会给大家讲到等等知识点,如果大家对本文有好的建议或者看到有不足之处,非常欢迎大家积极提出!在后续文章我会继续更新Golang相关的内容,希望对大家都有所帮助!

问题内容

我正在寻找这两种语言之间 FFI 的最小示例,一个调用 Fortran 库的 Go 程序的非常简单的 hello world。

我想强调,我不是在寻找外部资源、建议或教程,只是在 golang 中寻找最小的代码片段,以及 Fortran 中的相应格式。

此网站上有很多示例:

  • 从 fortran 调用 C(ifort、gfortran)
  • 从 Fortran 调用 C#
  • 从 Fortran 中读取 C++“Hello World”
  • 从 C 调用 Go 函数
  • 从 golang 调用 C
  • 从 C 调用 Haskell FFI 函数指针
  • 从 fortran 调用 python
  • 从 Rust 调用 Haskell
  • 如何从 Fortran 调用 R 函数?

Go -> Fortran 示例与这些示例一致,并且对其他开发人员有用。

编辑以解决重复声明

这个问题有一个答案,而链接到的问题则没有答案,因为这是一个重复的问题。关闭并重定向此问题作为可能以 -5 票结束的重复问题对于 stackoverflow 用户来说没有用,尽管两者都提出了一个合理的问题。


解决方案


cgo (https://golang.org/cmd/cgo/) 似乎提供了调用 c 的功能。所以我尝试使用它来调用 fortran(在 osx10.11 上使用 go-1.11 + gfortran-8.2),这似乎适用于这个简单的程序...

main.go:

package main

// #cgo ldflags: mylib.o -l/usr/local/cellar/gcc/8.2.0/lib/gcc/8 -lgfortran
// void hello();
// int  fort_mult( int );
// void array_test1 ( double*, int* );
// void array_test2_( double*, int* );
import "c"
import "fmt"

func main() {
    // print a message
    c.hello()

    // pass a value
    fmt.println( "val = ", c.fort_mult( 10 ) )

    k := c.int( 777 )
    fmt.println( "val = ", c.fort_mult( k ) )

    // pass an array
    a := []c.double {1, 2, 3, 4, 5.5555}
    n := c.int( len(a) )

    c.array_test1( &a[0], &n )  // pass addresses
    fmt.println( a )

    c.array_test2_( &a[0], &n )  // no use of iso_c_binding
    fmt.println( a )
}

mylib.f90:

subroutine hello() bind(c)
    print *, "hello from fortran"
end subroutine

function mult( x ) result( y ) bind(c,name="fort_mult")  ! can use a different name
    use iso_c_binding, only: c_int
    integer(c_int), value :: x
    integer(c_int) :: y

    y = x * 10
end function

subroutine array_test1( arr, n ) bind(c)   ! use iso_c_binding
    use iso_c_binding, only: c_int, c_double
    integer(c_int) :: n
    real(c_double) :: arr( n )

    arr(:) = arr(:) * 100.0d0
end subroutine

subroutine array_test2( arr, n ) ! no use of iso_c_binding (e.g. for legacy codes)
    integer :: n
    double precision :: arr( n )   ! or real(8) etc

    arr(:) = arr(:) * 2.0d0
end subroutine

编译:

gfortran -c mylib.f90
go build main.go
./main

结果:

Hello from Fortran
val =  100
val =  7770
[100 200 300 400 555.5500000000001]
[200 400 600 800 1111.1000000000001]

到这里,我们也就讲完了《从 go 调用 fortran 库的最小示例》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>