Ich versuche, eine native, nicht Thread-sichere Fortran-Bibliothek gleichzeitig mit JNA zu betreiben. Da die Bibliothek nicht Thread-sicher ist, versuche ich, verschiedene Kopien derselben Bibliothek zu instanziieren, aber scheinbar teilen sie sich Speicheradressen. Wenn ich eine Variable in einer Bibliothek ändere, wird die Variable in der anderen Bibliothek geändert. Dieses Verhalten macht es unmöglich, sie in separaten Threads auszuführen.Speicherprobleme beim Laden von zwei nativen Bibliotheken mit denselben Symbolen
Das folgende Codebeispiel zeigt, was ich meine:
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
Diese Datei kompiliert und kopiert wie folgt:
gfortran -shared -O2 code.f -o mylib.so -fPIC
cp mylib.so mylib_copy.so
Dann Zugriff über diese beiden I 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());
}
Die Ausgabe des obigen Codes ist 9
, was bedeutet, dass die beiden Bibliotheken ihren Speicher teilen.
Gibt es eine Möglichkeit, sie vollkommen unabhängig zu machen? Ich habe das gleiche mit Intel Fortran Compiler versucht, das gleiche Ergebnis.
Wie kann ich rtld_local herausfinden? Ich benutze CentOS 7 –
Ich bekomme das erwartete Verhalten mit der Einstellung 'RTLD_LOCAL = 1', obwohl ich denke,' RTLD_LOCAL' hat den Wert 0 (GLIBC2.4). Wenn ich 'RTLD_LOCAL = 0 'festlege, beschwert sich' Native.loadLibrary', dass die Bibliothek (d. H. Die So-Datei) nicht gefunden werden kann. PS: Es gibt keine solche Methode 'Native.loadLibrary' mit einer Signatur wie in Ihrer Antwort fehlt Ihnen die Interface-Klasse. –
Eventuell müssen Sie 'RTLD_LAZY' einbeziehen (das unter OSX einen Wert von" 1 "hat, kann Linux ATM nicht überprüfen). Definiere 'RTLD_LOCAL' nicht als" 1 ", das ist falsch. Es ist nichts falsch daran, einfach 'OPTIONS = 1' zu definieren und es dabei zu belassen; Es gibt keine Notwendigkeit, die Konstanten zu definieren, wenn niemand sonst diesen Teil des Codes wiederverwenden wird. – technomage