I'm trying to operate a native, non-thread-safe Fortran library concurrently using JNA. As the library is not thread-safe, I try to instantiate different copies of the same library, but apparently they seem to share memory addresses. If I modify one variable in one library, the variable in the other library is modified to. This behavior makes it impossible to run them concurently in separate threads.
The following code example demonstrates what I mean:
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
This file is compiled and copied as follows:
gfortran -shared -O2 code.f -o mylib.so -fPIC
cp mylib.so mylib_copy.so
Then I access those two using 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());
}
The output of the above code is 9
, whichs means the two libraries seem to share their memory.
Is there a way to make them completely independent? I tried the same using Intel Fortran compiler, same result.
JNA uses RTLD_LAZY|RTLD_GLOBAL when opening a library via
dlopen
, which is probably why the symbols are being shared. You can override those flags like so: