Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Arrays of strings in Fortran-C bridges using iso_c_binding

I'm writing code that will call a C function from Fortran using Fortran's C interoperability mechanism (introduced in Fortran 2003 and implemented in newer versions of gfortran and ifort).

This answer is almost what I need, but I can't quite get my head around what interface declaration I should use in Fortran for a C function that looks like this:

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;
}

I'm not clear what the declaration should be for the interface on the Fortran end:

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

I do know that I'll have to deal with the null-termination issue too.

like image 223
JoeZuntz Avatar asked Mar 13 '12 14:03

JoeZuntz


1 Answers

The way we do it is to use a C_PTR array to point to strings. For example:

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

then we set our strings in stringArray, remembering to null-terminate them such as:

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

and pass stringPtrs to the C function.

The C function has the interface:

void stringFunc(int *numStrings, char **stringArray) {
    int i;
    for(i=0;i<*numStrings;++i) {
       printf("%s\n",stringArray[i]);
    }
 }
like image 196
tpg2114 Avatar answered Sep 28 '22 01:09

tpg2114