使用iso_c_binding在Fortran-C桥接中的字符串数组

13

我正在编写代码,将使用Fortran的C互操作机制(在Fortran 2003中引入并在更新版本的gfortran和ifort中实现)从Fortran调用一个C函数。

这个答案几乎是我需要的,但我不能很好地理解针对以下C函数应该在Fortran中使用哪种接口声明:

int use_array(int n, char * array[]){
    int i;
    for(i=0; i<n; i++){
        printf("Item %d = %s\n",i,array[i]);
    }
    return n;
}

我不清楚Fortran端接口的声明应该是什么:

interface
    function use_array(n, x) bind(C)
        use iso_c_binding
        integer (c_int) use_array
        integer (c_int), value :: n
        character(c_char) WHAT_SHOULD_GO_HERE? :: x
    end function use_array
end interface

我知道我也必须处理空终止问题。


非常感谢用户francescalus的帮助,他有益地编辑了这个问题,通过删除结尾处的“谢谢”,使我看起来不那么客气。真是太好了,有像他们这样的用户阻止人们用日常礼貌让问题难以阅读。 - JoeZuntz
1个回答

10

我们的做法是使用一个 C_PTR 数组来指向字符串。例如:

CHARACTER(LEN=100), DIMENSION(numStrings), TARGET :: stringArray
TYPE(C_PTR), DIMENSION(numStrings) :: stringPtrs

然后我们将字符串设置在stringArray中,记得要以空字符结尾,例如:

DO ns = 1, numStrings
   stringArray(ns) = "My String"//C_NULL_CHAR
   stringPtrs(ns) = C_LOC(stringArray(ns))
END DO

并将stringPtrs传递给C函数。

C函数的接口如下:

void stringFunc(int *numStrings, char **stringArray) {
    int i;
    for(i=0;i<*numStrings;++i) {
       printf("%s\n",stringArray[i]);
    }
 }

非常感谢您的快速和有用的回复!为了完整起见,接口中的类型是“type(c_ptr),dimension(numStrings)”。 - JoeZuntz
在我们的代码中,实际上并没有为C函数提供接口,我们将其视为“external”,因此我手头没有一个简单的接口块示例。 - tpg2114
2
这不是标准的Fortran 2003(参见第15.2.1节)或2008(第15.3.2节):如果类型为字符,则长度类型参数仅在其值为一时可互操作。 gfortran使用C_LOC(带有*character(len=...)*)发出错误信号。在GCC bugzilla上也有关于此问题的讨论 - user1220978
1
Fortran 2018 提供了一种新的选择,详情请见:https://fortran-lang.discourse.group/t/return-an-array-of-strings-from-fortran-to-c/5100/7 - K. Shores

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接