2016-06-22 15 views
0

Ich bin ein Anfänger in R und ich versuche, eine .dll Datei mit dem Namen dll.dll, die in C geschrieben ist, in R zu laden. Es scheint zu arbeiten, jetzt möchte ich Verwenden Sie die Funktionen, die in der Datei .dll gespeichert sind, und ich Probleme auftreten..C() gibt mir eine leere Liste

Ich habe nach einer Lösung oder einer anderen Methode in Handbüchern gesucht, hier und auf Google. Wäre sehr dankbar, wenn ich einen Vorschlag bekommen könnte, was zu verwenden ist oder irgendeine Idee!

Mein Code:

setwd("C:/Users/MyUser/R") 
dyn.load("dll.dll") 
is.loaded("DLL_FUNK") 
# For some reason True with capital letters, not in lower case 
output <- .C("DLL_FUNK", in9 = as.integer(7)) 
#output # R Crashes before I can write this. 
# R Crashes 
# In outdata.txt: "in-value= 139375128" 

Die Funktion eine Zahl zurückgeben sollte, 1955. Aber ich kann nicht auf diesen Wert zu kommen scheinen. Was mache ich falsch?

Aktualisierung mit Code (Fortran als C runned), das ist der Code in Dll.dll:

subroutine dll_funk(in9) 
implicit none 

!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
!***  Declarations: variables, functions 
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
integer(4) :: in9 
!integer :: in9 


! Definitions of variables in the external function calls 
!!dec$ attributes c,alias :'dll_funk' :: dll_funk 
!dec$ attributes dllexport   :: dll_funk 
!dec$ attributes value    :: in9 

open(194,file='outdata.txt') 
write(194,*) 'in-value=', in9 
! in9 = 1955 
close(194) 

end subroutine 
!end function 

So, jetzt, wenn es läuft, R stürzt ab, aber bevor es zu meiner Datei schreibt (outdata.txt) aber es ist nicht meine Nummer, vielleicht eine Art Adresse ...

Eine andere Frage, empfehlen Sie mir, den Code mit .C auszuführen und von C den Fortran-Code auszuführen oder ist es besser, ihn auszuführen. Fortran mit nur Fortran Code? Es scheint, wie .Fortran haben Problem Strings Handhabung oder das ist, was ich von zu verstehen: Interface func .C and .Fortran

+0

Möglicherweise fehlt Ihnen in Ihrem Anruf ein '' '. Versuchen Sie es mit 'dyn.load (" 2dll.dll ")' – Magisch

+0

Endlich funktioniert es, indem Sie alle Definitionen löschen und den Code so einfach wie möglich machen. – Smrow

Antwort

3

Warum Sie bestanden hat keine Argumente auf Ihre C-Funktion dll_function? Wenn Sie verwenden, müssen Sie Funktionsargumente als eine Liste übergeben. 10 gibt die geänderte Liste zurück. Also, wenn du nichts passierst, bekommst du nichts.

Wie sieht Ihre C-Funktion dll_function aus? Beachten Sie, dass:

  1. dll_function muss eine void C-Funktion sein, ohne Rückgabewerte. Wenn diese Funktion etwas zurückgeben soll, muss sie durch Ändern der Funktionsargumente zurückkehren.
  2. Alle Funktionsargumente von dll_function müssen Zeiger sein.

Follow-up

Die dll_function ist nur zu testen, ob ich Zugang zu ihm bekommen können.

Sie können is.loaded() nach dyn.load() verwenden, um zu testen, ob Sie den Zugriff auf die C-Funktion haben:

dyn.load("dll.dll") 
is.loaded("dll_function") ## TRUE 

Beachten Sie, dass, is.loaded C-Funktionsname nimmt, während dyn.load().dll Namen nimmt. Im Allgemeinen können Sie mehrere Funktionen in einer einzigen .dll Datei haben. Sie können is.loaded() verwenden, um beide zu überprüfen, um zu testen, ob die gemeinsam genutzte Bibliothek erfolgreich geladen wurde.

Also wenn ich es etwas zurückgeben möchte, sollte ich es ein Argument geben (vom gleichen Typ?)?

Ja. Die andere Antwort gibt hier ein Spielzeugbeispiel. Du kannst einen Blick auf this answer werfen, die ich vor einem halben Monat gemacht habe. Unten finden Sie eine Zusammenfassung des Variablentyps.

0

Bei Verwendung von .C werden die zusätzlichen Argumente, die an .C übergeben wurden, kopiert und als Zeiger auf die aufgerufene c-Funktion übergeben. Diese Funktion kann dann den Datenzeiger durch die Zeiger ändern. Der Rückgabewert der Funktion wird von .C ignoriert. Also, Sie c-Funktion sollen in etwa so aussehen:

void dll_function(int* result) { 
    /* Do some complicated computation that results in 1955 */ 
    (*result) = 1955; 
} 

Und Ihren Anruf von R:

.C("dll_function", integer(1)) 

Ein Beispiel mit Eingang (diese berechnet die Summe eines ganzzahligen Vektor, in diesem Beispiel geht davon aus, dass es sind keine Werte im Vektor fehlt):

void dll_function2(int* result, int* vector, int* length) { 
    int sum = 0; 
    for (int i = 0; i < (*length); ++i, ++vector) { 
    sum += (*vector) 
    } 
    (*result) = sum; 
} 

von R Genannt:

x <- c(1000, 900, 55) 
.C("dll_function2", integer(1), as.integer(x), length(x))[[1]] 
+0

@ZheyuanLi Dachte darüber nach, es als Bearbeitung zu Ihrer Antwort hinzuzufügen, aber es schien ein bisschen zu groß für eine Bearbeitung. –

Verwandte Themen