2017-01-06 7 views
0

Ich versuche, eine Funktion in C zu erstellen, die von Fortran aufgerufen wird. Das wichtigste zuerst. Der Fortran-Code wird mit f77 kompiliert und das c wird mit gcc kompiliert. Beide sind in .so-Bibliotheken kompiliert. Die c-Funktion liest den Speicher auf einem Gerät an einer Adresse und in der vom Fortran angegebenen Größe. Ich bin in der Lage, die Adresse zu sehen, und Größe, die an das c übergeben wird, aber ich habe Probleme, die Daten in der c-Funktion zu füllen und es zum Fortran zurückzubringen. Siehe den entsprechenden Code unten. Meine Annahme ist, dass in der Speicherzuweisung oder in der Pointer-Syntax für die Datenvariable etwas nicht stimmt.C-Funktion von Fortran mit Zeigern aufrufen

C

void copymemory_(uint32_t *addr, int *size, uint8_t *data) 
{ 

    int i; 
    printf("addr %x \n", *addr); 
    printf("size %i \n", *size); 

    for (i = 0; i<*size; i++) 
    { 
     *data[i] = i; 
     printf("memory %i \n",*data[i]); 
    } 

} 

Fortran

integer memory(4) 
call copymemory(z'dead', 4, memory) 

DO i = 1,memsize 
    call printf(memory(i)) 
END DO 
+1

Warum denken Sie etwas nicht in Ordnung ist? Was passiert? Auf der Fortran-Seite, was sind "memsize" und "printf" und was macht das 'z'dead' wo es ist? Auf der C-Seite, warum 'uint8_t'? Warum können Sie die Standard-Interoperabilität von Fortran-C nicht nutzen? – francescalus

+0

Nun Kumpel, das ist ziemlich abhängig von Aufruf Konventionen ... Ich habe nie geschrieben Fortran-Code in meinem ganzen Leben, aber ich werde jetzt – DrPrItay

+0

Fehlermeldungen versuchen? Welche? Falsche Ergebnisse gedruckt? Wie sehen Sie aus? –

Antwort

2

ich Ihren Code mehrere Punkte haben.

Bitte liefern Sie kompilierbaren Code und beschreiben Sie die Ausgabe des genauen Codes!

Das beinhaltet die #include für Standard-Header, wenn Sie wollen, dass Menschen Ihren Code debuggen, machen Sie es ihnen einfach, so dass sie nicht suchen müssen, welche Zeilen Sie weggelassen haben, weil sie Ihnen "offensichtlich" erschienen. Einfach alles einfügen. Der Code sollte kompilieren, wenn von hier kopiert wird!

Sogar der ausführbare Teil Ihres Codes kompiliert nicht in meinem Compiler. Ich musste die *data zu data ändern. Sind Sie sicher, dass Sie Ihren tatsächlichen Code kopiert haben?

cfun.c: In function ‘copymemory_’: 
cfun.c:13:9: error: invalid type argument of unary ‘*’ (have ‘int’) 
     *data[i] = i; 
     ^
cfun.c:14:31: error: invalid type argument of unary ‘*’ (have ‘int’) 
     printf("memory %i \n",*data[i]); 
         ^

Ihr Fortran-Code enthält einen Aufruf zu einem gewissen printf Unterprogramm. Wo ist das definiert? Ist es in Ihrem tatsächlichen Code vorhanden? Ich bezweifle es. Bitte kopieren Sie nach StackOverflow immer einen vollständigen und kompilierbaren Code.

So, nachdem das Offensichtliche Ihrer aktuellen Code Fixierung ist:

#include <stdio.h> 
#include <stdint.h> 

void copymemory_(uint32_t *addr, int *size, uint8_t *data) 
{ 

    int i; 
    printf("addr %x \n", *addr); 
    printf("size %i \n", *size); 

    for (i = 0; i<*size; i++) 
    { 
     data[i] = i; 
     printf("memory %i \n",data[i]); 
    } 

} 


implicit none 

integer :: memsize = 4 

integer memory(4) 
integer i 

call copymemory(z'dead', 4, memory) 

DO i = 1,memsize 
    print *, (memory(i)) 
END DO 

END 

Es stürzt nicht ab, sondern memory in Fortran enthält Müll. Es muss, weil es integer ist und behandeln Sie es als int8_t in C.

So behandeln Sie es als ein Array von vier Ganzzahlen in C oder kopieren Sie es Byte für Byte, aber dann müssen Sie die richtige Anzahl von übergeben zu kopierende Bytes. Aus Ihrer Beschreibung ist nicht klar, welche ist Ihre Absicht, so werde ich nur eine Möglichkeit zeigen:

void copymemory_(uint32_t *addr, int *size, uint32_t *data) 

Der Ausgang korrekt ist dann:

> gfortran-4.10 -fsanitize=address cfun.c ffun.f90 
> ./a.out 
addr dead 
size 4 
memory 0 
memory 1 
memory 2 
memory 3 
      0 
      1 
      2 
      3 
+0

Nach viel mehr Forschung fand ich, dass es für meine Zwecke tatsächlich keine Lösung gibt. Die von Ihnen angegebene Lösung war korrekt und würde funktionieren, wenn ich den f77-Compiler nicht verwenden würde. f77 erlaubt nicht, von c nach fortran zu gehen, und mit dem Code, den du zur Verfügung gestellt hast, hatte das Fortran-Array immer Müll. Wenn ich f90 verwenden könnte, würde die von Ihnen angebotene Lösung funktionieren. – cwheat

+0

Jeder Compiler hat seine eigene Aufrufkonvention Grundsätzlich erlaubten alle F77-Compiler dies, aber es gibt keinen * "F77-Compiler" *, es gibt viele verschiedene Compiler und Sie müssen das Handbuch studieren, um herauszufinden, wie Sie das richtig machen. Dies ist nicht F77 vs F90, dies ist ein Compiler gegen verschiedene Compiler. Meine Lösung ist nicht Standard F90, es ist Gfortran spezifisch. Es gibt keine Standard-F90-Lösung, die Standard-C-Fortran-Interoperabilität ist F2003. –