加载两个包含相同符号的本机库时出现内存问题
Memory issues while loading two native libraries containing same symbols
我正在尝试使用 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
,这意味着两个库似乎共享它们的内存。
有没有办法让他们完全独立?我使用 Intel Fortran 编译器尝试了相同的结果。
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);
我正在尝试使用 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
,这意味着两个库似乎共享它们的内存。
有没有办法让他们完全独立?我使用 Intel Fortran 编译器尝试了相同的结果。
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);