带有 Fortran 假定大小数组的 JNA

JNA with Fortran assumed size array

我有一个采用假定大小数组的 Fortran 子例程:

subroutine sub(arr)
  implicit none
  double precision arr(*)
end subroutine

我使用 JNA 从 Java 进行了本机调用,Fortran 子例程被编译为共享库 mylib.so:

import com.sun.jna.Library;
import com.sun.jna.Native;

public class Wrapper {
    public interface MyLib extends Library {
        public void sub_(double[] arr);
    }

    public static void main(String[] args) {
        System.setProperty("jna.library.path", ".");
        MyLib lib = (MyLib) Native.loadLibrary("mylib.so", MyLib.class);
        double[] myarr = new double[10];
        lib.sub_(myarr);
    }
}

现在,有没有一种方法可以获取(在 Fortran 子例程中)我传递给该子例程的数组的大小,而无需将实际大小(在本例中为 10)作为附加参数传递?

我试过 (Fortran) print*, size(arr),但出现编译错误:

   print*,size(arr)
              1
Error: The upper bound in the last dimension must appear in the reference to the assumed size array ‘arr’ at (1)

您需要将长度作为附加参数传递。使用假定形状数组将不起作用,原因如下:

在大多数 Fortran 编译器使用的 ABI 中,作为参数的数组 ("dummy arguments") 可以采用两种表示形式之一,具体取决于 subroutine/function:

中使用的接口
  • 那些以已知大小或假定大小传递的,如arr(n)arr(*),通常只接收指向第一个元素的指针,其中元素假定是连续的。
  • 那些以假设形状传递的,比如arr(:)接收一个数组描述符结构。这完全取决于实现,但通常这样的结构包含指向数据第一个元素的指针加上关于每个维度的边界、步幅等的信息

这就是为什么您可以直接传递数组的单行或偶数索引中的元素(如果函数将其作为假定形状数组接收)的原因:描述符结构对数据是数据的信息进行编码不一定是连续的,因此 Fortran 编译器不需要将 arr(5:2:) 复制到内存中的临时位置。

你不能使用这样的设施与Java通信的原因是描述符结构是完全非标准的,是每个编译器特定ABI的一部分。因此,即使您以某种方式设法理解了如何构建它(这将是非常重要的),您的编译器的下一个版本也可能带来彻底的改变。