我有一个 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 中,作为参数(“虚拟参数”)的数组可以采用两种表示形式之一,具体取决于子例程/函数中使用的接口:
- 那些通过已知尺寸或假设尺寸, like
arr(n)
or arr(*)
,通常只接收指向第一个元素的指针,并且假定元素是连续的。
- 那些通过了假设的形状, like
arr(:)
收到一个数组描述符结构。这完全依赖于实现,但通常这样的结构包含指向数据第一个元素的指针plus有关每个维度的边界、步幅等的信息。
这就是为什么如果函数将其作为假定形状数组接收,则可以直接传递数组的单行或仅传递偶数索引中的元素:描述符结构对数据不一定是连续的信息进行编码,因此Fortran编译器不需要复制arr(5:2:)
到内存中的临时位置。
不能使用此类工具与 Java 通信的原因是描述符结构完全不标准,是每个编译器特定 ABI 的一部分。因此,即使您以某种方式设法理解如何构建它(这将是不平凡的),编译器的下一个版本也可能带来彻底的改变。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)