Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Arrays 具有Fortran假定大小数组的JNA_Arrays_Fortran_Jna - Fatal编程技术网

Arrays 具有Fortran假定大小数组的JNA

Arrays 具有Fortran假定大小数组的JNA,arrays,fortran,jna,Arrays,Fortran,Jna,我有一个Fortran子程序,它采用假定大小的数组: subroutine sub(arr) implicit none double precision arr(*) end subroutine 我使用JNA从Java进行了本机调用,Fortran子例程被编译为一个共享库mylib。因此: import com.sun.jna.Library; import com.sun.jna.Native; public class Wrapper { public interfa

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

subroutine sub(arr)
  implicit none
  double precision arr(*)
end subroutine
我使用JNA从Java进行了本机调用,Fortran子例程被编译为一个共享库
mylib。因此

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中,数组作为参数(“伪参数”)可以采用两种表示形式之一,具体取决于子例程/函数中使用的接口:

  • 以已知大小或假定大小传递的对象,如
    arr(n)
    arr(*)
    ,通常只接收指向第一个元素的指针,并且假定元素是连续的
  • 通过假定形状传递的对象,如
    arr(:)
    接收数组描述符结构。这完全依赖于实现,但通常这种结构包含指向数据第一个元素的指针,以及关于每个维度边界、跨步等的信息
这就是为什么如果函数将数组作为假定形状数组接收,则可以直接传递一行或仅传递偶数索引中的元素的原因:描述符结构对数据不一定是连续的信息进行编码,因此Fortran编译器不需要复制
arr(5:2:)
到内存中的临时位置


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

实际上,描述符的主要部分现在在TS中标准化,TS将成为Fortran 2015的一部分。在Cm中甚至有使用假定形状数组的标准头,但我不知道是否有编译器实际提供了它们。不幸的是,gfortran的描述符仍然与其他编译器大不相同。@VladimirF在F2015中标准化的问题是,大多数编译器甚至没有实现F2008的全部功能。你需要考虑一个显著的延迟,很容易10年,如果某些特性被假定为“普遍可用”的标准兼容方式。例如,“英特尔Fortran 12.0”(2011?)没有实现Fortran 2003中的
ALLOCATE(x,SOURCE=y)
语句。它的标准化只是为了描述编译器实际使用的内容。英特尔实际上已经实施了多年的标准版本。Gfortran开发人员也知道他们需要改变它很多年,但他们有一些复杂问题。我必须纠正我以前的评论。在这台服务器上的另一个地方,Intel的Steve Lionel指出,标准数组描述符只涉及可与C互操作的过程。在Fortran中,编译器可以使用并且经常使用描述符的其他格式。1)Intel Fortran 17支持所有F2015“与C进一步互操作”功能,包括延迟形状数组的C描述符。Javier需要在Fortran过程声明中添加BIND(C),Java代码需要构造一个依赖于实现的C描述符。(描述符的某些布局是特定于编译器的-编译器提供了一个带有布局的.h文件。)2)Vladimir认为C描述符不用于调用没有BIND(C)的Fortran例程是正确的。在我看来,通过长度是这里最简单的方法。