加载包含相同符号的两个本机库时内存问题

时间:2016-07-27 18:58:56

标签: fortran native jna

我正在尝试使用JNA同时运行本机的,非线程安全的Fortran库。由于库不是线程安全的,我尝试实例化同一个库的不同副本,但显然它们似乎共享内存地址。如果我修改一个库中的一个变量,则将另一个库中的变量修改为。此行为使得无法在单独的线程中以完全方式运行它们。

以下代码示例演示了我的意思:

code.f:

  subroutine set(var)
     implicit none
     integer var,n
     common/conc/n
     n=var
  end subroutine

  subroutine get(var)
     implicit none
     integer var,n
     common/conc/n
     var=n
  end subroutine

此文件的编译和复制如下:

gfortran -shared -O2 code.f -o mylib.so -fPIC
cp mylib.so mylib_copy.so

然后我使用JNA访问这两个:

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.ptr.IntByReference;

public class JNA {
    public interface MyLib extends Library {
        public void set_(IntByReference var);
        public void get_(IntByReference var);
    }

    public static void main(String[] args) {
        System.setProperty("jna.library.path", ".");
        MyLib lib = (MyLib) Native.loadLibrary("mylib.so", MyLib.class);
        MyLib lib_copy = (MyLib) Native.loadLibrary("mylib_copy.so", MyLib.class);

        # set a common variable in mylib
        lib.set_(new IntByReference(9));

        # access the variable in mylib_copy
        IntByReference result = new IntByReference();
        lib_copy.get_(result);
        System.out.println(result.getValue());

    }

上述代码的输出为9,这意味着两个库似乎共享其内存。

有没有办法让它们完全独立?我尝试使用英特尔Fortran编译器,结果相同。

1 个答案:

答案 0 :(得分:2)

JNA在通过dlopen打开库时使用RTLD_LAZY | RTLD_GLOBAL,这可能是共享符号的原因。您可以像这样覆盖这些标志:

int RTLD_LOCAL = ??; // look this up on your system
Map options = new HashMap();
options.put(Library.OPTION_OPEN_FLAGS, RTLD_LOCAL);
MyLib mylib = Native.loadLibrary("mylib", MyLib.class, options);
MyLib mylib2 = Native.loadLibrary("mylib2", MyLib.class, options);