Showing results for 
Search instead for 
Did you mean: 

Returning string to Java from Fortran using JNA

I've done a lot of trial-and-error, a lot of Googling, and yet can't get this to work.

I'm simply trying to have a fortran sub return an arbitrary string to a Java method using JNA. I'm using subroutines rather than functions because I would like to extend the idea to return a number of values.

Here's my latest fortran attempt:

    subroutine string_out_fortran (output_string) bind (C, name="fortran_string_out")
        use iso_c_binding, only: C_CHAR, c_null_char
        implicit none

        character(32) :: regular_string
        integer :: output_string_len
        character(kind=c_char, len = :), allocatable, dimension(:), intent(out) :: output_string

        integer :: i

        regular_string = "An output string"
        output_string_len = len(regular_string)

        ! create space for string to output
        allocate (character(len = 1) :: output_string(output_string_len + 1))

        ! copy arbitrary string to array of chars with null ending.
        loop_string: do i=1, output_string_len
           output_string(i) = regular_string(i:i)
        end do loop_string
        output_string(output_string_len + 1) = c_null_char

    end subroutine string_out_fortran

And here is my Java code using JNA:

public static void main(String[] args) {
        PointerByReference pp = new PointerByReference();

        final Pointer p = pp.getValue();
        // extract the null-terminated string from the Pointer
        final String val = p.getString(0);
        System.out.println("Output string:" + val);

I get an empty string as val. I'm on Mac using the 16.0.3 compiler. Can anyone give me any ideas to try?



0 Kudos
1 Reply

Oh, my...  You're expecting a Fortran deferred-length, allocatable, deferred-shape array to be interoperable with, what, a single pointer? Um, no.

In earlier versions that source wouldn't even compile. In version 16 we support the Fortran 2015 "Further Interoperability with C" features which accepts this but the compiler expects a "C descriptor" to be received (this is a structure defined by the Fortran standard whose structure is declared in the header file ISO_Fortran_binding.h.) You can read some more about that here.

If you want to try translating the C descriptor structure to Java you could make this work. Otherwise you could declare output as type C_PTR (from module ISO_C_BINDING), and then use C_F_POINTER to convert it to a pointer to an an array of characters which you then allocate to the desired size and fill in.

0 Kudos