10

我正在尝试编译和链接调用 c 子例程的 Fortran 代码:

Fortran 代码:

program adder
integer a,b
a=1
b=2
call addnums(a,b)
stop    
end program

C代码:

void addnums( int* a, int* b ) 
{
    int c = (*a) + (*b);  /* convert pointers to values, then add them */
    printf("sum of %i and %i is %i\n", (*a), (*b), c );
}

我使用以下命令在 windows 环境中编译和链接。

ifort -c adder.f
cl -c addnums.c
ifort -o add adder.obj addnums.obj

我收到以下错误:

Microsoft (R) Incremental Linker Version 8.00.50727.762
Copyright (C) Microsoft Corporation.  All rights reserved.
-out:add.exe 
-subsystem:console 
adder.obj 
addnums.obj 
adder.obj : error LNK2019: unresolved external symbol ADDNUMS referenced in function MAIN__
add.exe : fatal error LNK1120: 1 unresolved externals

请帮我解决这个问题?谢谢。

4

2 回答 2

17

您需要在 Fortran 主程序的规范部分中为 C 函数提供一个接口主体,告诉 Fortran 编译器该名称addnums是一个 C 函数。就像是:

INTERFACE
  SUBROUTINE addnums(a, b) BIND(C)
    USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_INT
    IMPLICIT NONE
    INTEGER(C_INT) :: a, b
  END SUBROUTINE addnums
END INTERFACE

(对于那些没有特殊选项的平台上的编译器,默认的整数类型与 C_INT 相同 - 但如果编译器/平台或编译选项发生变化,明确整数类型有助于保护您。)

于 2013-07-24T23:41:17.940 回答
2

这是我可以立即看到的两件事(我主要使用 FORTRAN77,因此这可能不是最新或最好的方法):

  1. 由于您的 C 函数是一个函数(而不是子例程),因此您需要将“addnums”声明为 EXTERNAL。将此添加到您的声明部分的代码中。

    EXTERNAL addnums
  2. 在 C 代码中的函数名称中添加下划线。FORTRAN 会自动对其自己的函数执行此操作,但不会对其他语言的函数执行此操作。所以,函数的签名是

    void addnums_( int* a, int* b )

这个页面对混合 C 和 FORTRAN 有很好的概述。希望这有帮助!

于 2013-07-24T23:51:38.590 回答