带有Fortran的JNA假定了大小数组 [英] JNA with Fortran assumed size array

查看:196
本文介绍了带有Fortran的JNA假定了大小数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 子程序子(arr)
隐式无
双精度arr(*)
结束子程序

Java使用JNA,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);


$ / code $ / pre

现在有没有办法让Fortran子程序)我传入此子程序而不传递实际大小(在本例中为10)作为附加参数的数组大小?我试过(Fortran) print *,size(arr),但是这给出了一个编译器错误:

pre $ print *,size(arr)
1
错误:最后一个维度的上限必须出现在(1)


解决方案

您需要将长度作为附加参数传递。使用假设形状的数组将不起作用,原因如下:在大多数Fortran编译器使用的ABI中,数组作为参数(伪参数)可能会采用以下之一两个表示,取决于子例程/函数中使用的接口:


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



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

您不能使用这些工具与Java通信的原因是描述符结构完全是非标准的,是每个编译器的特定ABI的一部分。因此,即使您以某种方式设法了解如何构建它(并且这不是微不足道的),但您的编译器的下一个版本可能会带来全面更改。


I have a Fortran subroutine taking an assumed size array:

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

I made a native call from Java using JNA, the Fortran subroutine is compiled as a shared library 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);
    }
}

Now, is there a way to get (in the Fortran subroutine) the size of the array I passed into this subroutine without passing the actual size (10 in this case) as an additional argument?

I tried (Fortran) print*, size(arr), but that gives a compiler error:

   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)

解决方案

You will need to pass the length as an additional parameter. Using an assumed-shape array will not work, here's why:

In the ABI employed by most Fortran compilers, arrays as parameters ("dummy arguments") can take one of two representations, depending on the interface used in the subroutine/function:

  • Those passed with known sizes or assumed sizes, like arr(n) or arr(*), usually receive just a pointer to the first element, with elements assumed to be contiguous.
  • Those passed with assumed shapes, like arr(:) receive an array descriptor structure. This is completely implementation dependent, but usually such a structure contains the pointer to the first element of the data plus information on the bounds of each dimension, the stride, etc.

That is the reason why you can directly pass a single row, or only the elements in even indices, of an array if the function receives it as an assumed shape array: the descriptor structure encodes the information that the data is not necessarily contiguous and so the Fortran compiler does not need to copy arr(5:2:) to a temporary location in memory.

The reason why you cannot use such facilities to communicate with Java is that the descriptor structure is completely non-standard, a part of the particular ABI of each compiler. Thus, even if you somehow managed to understand how to build it (and it would be non trivial) the next version of your compiler could bring a total change.

这篇关于带有Fortran的JNA假定了大小数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆