我有一个大型的混合C/Fortran代码库,目前在Windows上使用Intel工具进行编译。现在被要求将其迁移到GNU工具,在Linux上进行编译。我随意选择了版本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
这解决了链接错误,但它改变了字符串参数的处理方式;不再提供长度参数。所以要使用此方法,我不仅需要为每个当前采用这种方式的函数添加接口定义,还需要更改每个调用该函数的字符串处理方式,确保所有字符串都是以空字符结尾。
我可以通过将所有这样的函数转换为小写来解决问题,但是因为Intel编译器仍然生成大写符号,所以这将破坏现有的构建。
由于有大约2000个这样的函数,看起来这似乎是一项难以实现的工作。那么,我的问题是:如何在不改变函数调用语义和不使用Intel编译器破坏现有构建的情况下解决链接错误?
size_t
,而GFortran使用int
。在32位系统上这没问题,但在64位系统上传递多个字符串时会出现严重错误,而且链接器甚至无法捕获到这个错误。 - Tristan BrindleC_NULL_CHAR
。 - Stefan