GNU Fortran和C互操作性

时间:2014-10-15 05:01:26

标签: c++ c fortran gfortran language-interoperability

我有一个大型的混合C / Fortran代码库,目前使用Windows上的英特尔工具进行编译。我被要求将它移植到Linux上的GNU工具。或多或少随意,我选择了4.8版本。

从Fortran调用C函数时,互操作性通常如下所示:

// C code:
void PRINTSTR(char *str, size_t len) {
    for(int ii = 0; ii < len; ii++) {
        putchar(str[ii]);
    }
    putchar('\n');
}

!Fortran code:
program test
implicit none
call printstr("Hello, world.")
end

英特尔Fortran编译器始终生成大写符号,因此可以正常工作。但是GNU Fortran编译器总是生成小写符号,因此存在链接器错误。

GNU Fortran编译器曾经有一个名为-fcase-upper的选项,它使它生成大写符号,但似乎这对于每个人的好而言都是可配置的并且已被删除(我不确定何时)。

可以使用ISO_C_BINDING工具强制编译器生成区分大小写的名称:

program test
interface
subroutine printstr(str) bind(C, name='PRINTSTR')
character :: str(*)
end subroutine
end interface

call printstr("Hello, world.")
end

这解决了链接器错误,但它改变了字符串参数的处理方式;不再提供length参数。因此,要使用此方法,我不仅必须为当前以这种方式工作的每个函数添加接口定义,而且还必须在每次调用此类函数时更改字符串的处理方式,确保所有字符串是以空值终止的。

我可以通过小写来完成所有这些函数,但当然英特尔编译器仍会生成大写符号,这样就会破坏现有的构建。

由于有大约2,000个这样的功能,这似乎是不可行的工作量。所以,我的问题是:如何在不改变函数调用语义的情况下解决链接错误,并且不使用英特尔编译器破坏现有构建?

1 个答案:

答案 0 :(得分:2)

要解决链接器错误,您可以通过其他方式执行此操作。使用英特尔编译器选项names将外部名称转换为小写以匹配默认的GNU Fortran选项。并将中的名称转换为小写:

void printstr(char *str, size_t len) {...}

我个人建议使用-funderscoring和英特尔/assume:underscore来区分旨在实现互操作性的功能。

// C code:
void printstr_(char *str, size_t len) {...}

!Fortran code:
program test
implicit none
call printstr("Hello, world.")
end