为什么将我的程序与iso_c_binding链接会导致对__gfortran_的未定义引用?

时间:2018-01-14 07:08:42

标签: c++ c fortran fortran-iso-c-binding

我有一个遗留的Fortran代码,我希望与新的C / C ++程序混合使用。

Fortran子例程动态分配一些我想传递给c程序的数组。运行Fortran代码后,我只能获得这些数组的大小。

在这个论坛中得到一些提示后,我得到了以下代码,我认为它最好编译,链接和运行。

实际上我可以单独编译我​​的C代码和我的Fortran代码,但它没有链接给出以下错误:

undefined reference to _gfortran_runtime_error

undefined reference to _gfortran_os_error

我正在使用g ++和GFortran编译器版本5.4.0,并使用g ++和选项-lg fortran链接两个.o文件。

fortran代码:

subroutine test_allocation(outp) bind(c)
    use iso_c_binding
    implicit none
    type (c_ptr), value :: outp
    integer, target ::b(2)
    integer(c_int), pointer :: a(:)
    b(1)=1
    b(2)=2
    allocate(a(2))
    a=>b
    call c_f_pointer(outp, a,[2])
end subroutine

c code:

#include <iostream>
using namespace std;
extern "C" void test_allocation(int ** ptr);
int main ()
{
        int* ptr;
        test_allocation(&ptr);
}

编辑:

正如Vladimir F在评论中所说,我的编译器选项出现了错误。正确的是-lgfortran。

现在它正在连接,但结果不是我所期望的。我改变了一点我的代码来表明这一点:

Fortran代码:

subroutine test_allocation(outp) bind(c)
    use iso_c_binding
    implicit none
    type (c_ptr), value :: outp
    integer, target ::b(2)
    integer(c_int), pointer :: a(:)
    b(1)=1
    b(2)=2
    allocate(a(2))
    a=>b
    print*, "a(1) in Fortran: ", a(1)
    print*, "a(2) in Fortran: ", a(2)
    call c_f_pointer(outp, a,[2])
    print*, "outp after c_f_pointer: ",  outp
end subroutine

C代码:

#include <iostream>

using namespace std;

extern "C" void test_allocation(int** ptr);



int main ()
{
        int* ptr;
        test_allocation(&ptr);
        cout<<"ptr[0] in C: "<< ptr[0]<<endl;
        cout<<"ptr[1] in C: "<< ptr[1]<<endl;

}

输出结果为:

a(1) in fortran:            1
a(2) in fortran:            2
outp after c_f_pointer:       140726088663920
ptr[0] in C: 1447122753
ptr[1] in C: 1107265857

我也尝试将extern函数的声明更改为以下内容,但它仍然不起作用:

extern "C" void test_allocation(int*& ptr);
... 
test_allocation(ptr);

输出结果为:

a(1) in fortran:            1
a(2) in fortran:            2
outp after c_f_pointer:       140729541703872
ptr[0] in C: 1447122753
ptr[1] in C: 1107265857

1 个答案:

答案 0 :(得分:0)

现在它有效。我没有使用C_F_POINTER,而是使用了函数C_LOC

我还从VALUE声明中删除了参数TYPE(C_PTR)

以下是代码:

subroutine test_allocation(outp) bind(c)
    use iso_c_binding
    implicit none
    type (c_ptr)    :: outp
    integer  ::b(2)
    integer,dimension(:), pointer :: a
    b(1)=1
    b(2)=2
    allocate(a(2))
    a=b
    print*, "a(1) in fortran: ", a(1)
    print*, "a(2) in fortran: ", a(2)
    outp=c_loc(a)
    print*, "outp after c_loc: ",  outp
end subroutine

及其输出:

a(1) in fortran:            1
a(2) in fortran:            2
outp after c_loc:              36866928
ptr[0] in C: 1
ptr[1] in C: 2

以下链接对我帮助很大,虽然我没有使用intel编译器:

https://software.intel.com/en-us/forums/intel-fortran-compiler-for-linux-and-mac-os-x/topic/269660