5

我有一个大型的混合 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

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

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

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

4

1 回答 1

2

要解决链接器错误,您可以采取其他方式。使用英特尔编译器选项名称将外部名称转换为小写,以匹配默认的 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
于 2014-10-15T07:13:27.030 回答