GNU Fortran和C互操作性

Tom*_*Tom 5 c c++ fortran language-interoperability gfortran

我有一个大的,混合的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
Run Code Online (Sandbox Code Playgroud)

英特尔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
Run Code Online (Sandbox Code Playgroud)

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

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

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

Pet*_*ter 2

要解决链接器错误,您可以采用其他方法。使用英特尔编译器选项名称将外部名称转换为小写,以匹配默认的 GNU Fortran 选项。并将中的名称也转换为小写:

void printstr(char *str, size_t len) {...}
Run Code Online (Sandbox Code Playgroud)

我个人建议使用-funderscoring和 Intel/assume:underscore来区分用于互操作性的功能。

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

!Fortran code:
program test
implicit none
call printstr("Hello, world.")
end
Run Code Online (Sandbox Code Playgroud)