我有一个大型的混合 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 个这样的功能,这似乎是一个不可行的工作量。所以,我的问题是:如何在不更改函数调用语义和不破坏使用英特尔编译器的现有构建的情况下解决链接错误?