Arrays 具有Fortran假定大小数组的JNA
我有一个Fortran子程序,它采用假定大小的数组: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
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(:)
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例程是正确的。在我看来,通过长度是这里最简单的方法。