2016-05-18 13 views
0

Ich entschuldige mich, wenn dies eine einfache Frage für einige Leute ist, aber ich kann nirgendwo die Lösung finden. Ich bin ein RStudio Anfänger und ich möchte bestimmte Routinen eines Open-Source-Fortran77-Simulationsprogramm (es gibt auch C und C++ Code drin) aus RStudio aufrufen. Das Fortran-Programm verwendet Makefiles zum Kompilieren und es generiert viele .o-Objektdateien (übrigens verwende ich Unix). Ich habe eine Wrapper-Datei in fortran geschrieben, die zusammen mit dem Simulationsprogramm kompiliert wird und von RStudio zum Aufruf der Fortran-Routinen verwendet werden soll. Ich generiere die gemeinsame Objektdatei .so dieser Wrapper-Datei und alles funktioniert gut, wenn ich einfache Berechnungen in dieser Wrapper-Datei habe. Ich bin nach dem gleichen Verfahren wie in diesem hervorragenden Beitrag: http://www.r-bloggers.com/fortran-and-r-speed-things-up/rududio nennt Fortran Subroutinen - undefined Symbol Fehler

Ich benutze dyn.load und .Fortran erfolgreich und ich Ergebnisse zurück, solange ich nicht nennen Subroutinen, die in einer anderen Datei befinden (und entsprechen andere Objektdateien und andere .so-Dateien). Wenn ich versuche, ein anderes Unterprogramm aufruf aus dem Wrapper Unterprogramm erhalte ich folgende Fehlermeldung:

Error in dyn.load("rwrapper.so") : 
    unable to load shared object '/home/adminuser/ESP-rSource/src/esrubps/rwrapper.so': 
    /home/adminuser/ESP-rSource/src/esrubps/rwrapper.so: undefined symbol: runit_ 

runit (ohne Unterstrich) ein anderes Unterprogramm, das in einer anderen Datei befindet und eine andere Objekt-Datei. Ich habe dann versucht, eine zweite gemeinsame Objektdatei für diese Runit-Unterroutine zu erstellen, und ich lade sie auch mit dyn.load, aber das Problem wurde nicht behoben. Ich mache hier wahrscheinlich etwas falsch, aber ich weiß nicht was. Muss ich alle Objektdateien in .so Shared-Object-Dateien konvertieren und dann dyn.load verwenden, um jeden von ihnen zu laden (es gibt ungefähr 100 von .o-Dateien) oder würde der "Wrapper/Kommunikation" -Dateiansatz funktionieren? Gibt es eine Möglichkeit, eine Kommunikation zwischen dem Fortran-Programm und RStudio herzustellen? Ich bin mein RStudio Skript nur hier für Informationen einfügen (beachten Sie, dass die zweite dyn.load keinen Unterschied macht):

myrwrapper <- function(rrrandom) { 
    if (!is.loaded('rwrapper')) { 
    dyn.load("rwrapper.so") 
    } 
    if (!is.loaded('esru_lib')) { 
    dyn.load("./home/adminuser/ESP-rSource/src/lib/esru_lib.so") 
    } 
    retvals <- .Fortran("RXCHNGE",icomp = as.integer(2), rCOUPLEVAR = as.numeric(rrrandom)) 
    return(retvals$rCOUPLEVAR) 
} 

Eine einfache Lösung wäre gewesen, eine Textdatei von beiden Programme zu schreiben/lesen und Austausch Daten durch diese Datei, aber mein Verständnis ist, dass dies die Simulationen sehr langsam machen würde, da ich fast jedes Mal eine Datei öffnen/schließen muss, und so versuche ich, einen solchen Ansatz zu vermeiden. Vielen Dank für Ihre Hilfe.

+0

Da es noch keine Antwort gibt, sollte ich versuchen zu vereinfachen, was ich oben sage. 1. \t Ich benutze RStudio (dyn.load und. Fortran), um eine Fortran-Routine aufzurufen. 2. \t Wenn die Fortran-Routine einfache interne Berechnungen hat, erhalte ich in RStudio eine gültige Antwort 3. \t Wenn die Fortran-Routine einen Aufruf an eine andere Unterroutine in einer anderen Datei hat, schlägt das Ganze fehl und RStudio gibt eine Nachricht, die besagt Der Name dieser Subroutine ist ein nicht definiertes Symbol. Es fügt auch einen Unterstrich "_" nach dem Namen des Unterprogramms ein. Das Aufrufen einer anderen Subroutine innerhalb derselben Datei scheint gut zu funktionieren. – Spartan

Antwort

0

Das war eigentlich viel einfacher als ich dachte. Es war ein Anfängerfehler mit der freigegebenen .so-Datei. Das Problem wurde gelöst, wenn die freigegebene Datei erstellt und mit zwei (oder mehr) Objektdateien verknüpft wurde. Wenn Sie beispielsweise 1.F haben, das 2.F aufruft, und die entsprechenden 1.o und 2.o, sollten Sie beide Dateien beim Erstellen der gemeinsamen Datei einschließen: gfortran -shared -o 1plus2.so 1.o 2. o

Verwandte Themen