我有一个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)
1 回答
您需要将长度作为附加参数传递 . 使用假定形状的数组将不起作用,这是为什么:
在大多数Fortran编译器使用的ABI中,作为参数的数组(“伪参数”)可以采用两种表示形式之一,具体取决于子例程/函数中使用的接口:
以已知大小或假定大小传递的那些,如
arr(n)
或arr(*)
,通常只接收指向第一个元素的指针,假定元素是连续的 .以假定形状传递的那些,如
arr(:)
,接收数组描述符结构 . 这完全取决于实现,但通常这样的结构包含指向数据的第一个元素的指针以及关于每个维度的边界,步幅等的信息 .这就是为什么你可以直接传递一个数组的单行,或者只传递数组偶数索引中的元素的原因,如果函数将它作为一个假定的形状数组接收它:描述符结构对数据不一定是连续的信息进行编码等等 . Fortran编译器不需要将
arr(5:2:)
复制到内存中的临时位置 .您不能使用此类工具与Java通信的原因是描述符结构完全是非标准的,是每个编译器的特定ABI的一部分 . 因此,即使你以某种方式设法理解如何构建它(并且它将是非常重要的),下一版本的编译器也可能带来全面的变化 .