Erstellen einer FORTRAN-Schnittstelle für eine C-Funktion, die ein char * zurückgibt

7

Ich bin seit ungefähr einer Woche hierauf gestanden und habe Forum für Forum nach einer klaren Erklärung gesucht, wie man ein Zeichen * von C nach FORTRAN schickt. Um die Sache frustrierender zu machen, war das Senden eines char * -Arguments von FORTRAN an C geradlinig ...

Senden eines char * -Arguments von FORTRAN an C (das funktioniert):

%Vor%

Und von FORTRAN:

%Vor%

Wenn ich versuche, eine analoge Logik zu verwenden, um char * von C zurückzugeben, bekomme ich ein Problem nach dem anderen. Ein Versuch, den ich fühlte, sollte funktionieren:

%Vor%

Und die FORTRAN-Schnittstelle:

%Vor%

(Ich kann die DIMENSION (*) nicht wörtlich nehmen, also habe ich eine Übergröße von 255.)

Dieser sollte einen Zeiger auf ein Array von 255 C-Style-Zeichen zurückgeben - aber wenn dies der Fall ist, konnte ich dies nicht in eine aussagekräftige Zeichenfolge konvertieren. In der Praxis gibt es eine zufällige Menge von Zeichen zurück, von Wingdings bis zum "Bell" -Charakter ...

Ich habe auch versucht zurückzukehren:

  • Ein Zeiger auf CHARACTER (LEN = 255, KIND = C_CHAR).
  • Wörtlich ZEICHEN (LEN = 255, KIND = C_CHAR).
  • Ein INTEGER (C_SIZE_T), und versucht, das in einen Zeiger auf ein String-Array zu verfeinern.
  • Ein Zeichen.
  • usw.

Wenn mir jemand ein Beispiel dafür geben könnte, wäre ich sehr dankbar ...

Mit freundlichen Grüßen

Mike

    
Mike Sadler 02.04.2012, 07:58
quelle

6 Antworten

12

Strings mit dynamischer Länge sind mit der C-Interaktion immer etwas knifflig. Eine mögliche Lösung ist die Verwendung von Zeigern.

Zuerst ein einfacher Fall, in dem Sie eine mit Nullzeichen abgeschlossene Zeichenfolge an eine C-Funktion übergeben müssen. Wenn Sie die Zeichenfolge wirklich nur übergeben, müssen Sie sicherstellen, dass sie mit c_null_char abgeschlossen wird, daher ist diese Richtung ziemlich einfach. Hier sind Beispiele aus einer LuaFortran-Schnittstelle :

%Vor%

Und die Schnittstelle von lua_getfield sieht folgendermaßen aus:

%Vor%

Und die C-Code-Schnittstelle ist:

%Vor%

Nun der etwas komplexere Fall, in dem wir uns mit einer zurückgegebenen Zeichenfolge von C mit einer dynamischen Länge beschäftigen müssen. Die portabelste Lösung, die ich bisher gefunden habe, ist die Verwendung von Zeigern. Hier ist ein Beispiel mit einem Zeiger, wo die Zeichenfolge von der C-Routine (auch von der Aotus-Bibliothek oben erwähnt):

%Vor%

Dabei hat lua_tolstring die folgende Schnittstelle :

%Vor%

Abschließend soll hier geklärt werden, wie ein c_ptr als Fortran-Zeichenkette interpretiert werden kann: Angenommen, Sie haben ein c_ptr, das auf die Zeichenfolge verweist:

%Vor%

Und die Länge davon wird durch eine len-Variable vom folgenden Typ angegeben:

%Vor%

Sie möchten diese Zeichenfolge in einem Zeiger auf eine Zeichenfolge in Fortran abrufen:

%Vor%

Also machst du das Mapping:

%Vor%     
haraldkl 02.04.2012, 09:23
quelle
5

Mein Dank geht an heraldkl , weil er mir die Lösung für dieses sehr frustrierende Problem gegeben hat. Ich poste, was ich schließlich implementiert habe, das die Zeigerumwandlung in die Schnittstelle rollt, bedeutend, die abschließende Anwendung kann die C-Funktion aufrufen, ohne über die Zeigerumwandlung zu wissen:

Die C-Funktion:

%Vor%

Das FORTRAN-Schnittstellenmodul:

%Vor%

Und um diese Funktion von einem FORTRAN-Programm aufzurufen:

%Vor%

Nochmals vielen Dank an heraldkl für die Bereitstellung dieser Lösung - ich hätte keine Ahnung gehabt, wie ich das machen könnte seine Eingabe.

    
Mike Sadler 03.04.2012 08:20
quelle
4

Dieser Thread ist ein wenig alt, aber da ich ein ähnliches Problem hatte (und wahrscheinlich auch andere), poste ich trotzdem eine Antwort.

Die oben angegebenen Codes verursachen einen Segmentierungsfehler, wenn die C-Zeichenfolge aus irgendeinem Grund null ist. Darüber hinaus ist es nicht erforderlich, eine Zeichenfolge mit 255 Zeichen zurückzugeben (die wahrscheinlich vor der Verwendung getrimmt werden muss), da Fortran 2003/2008 Funktionen unterstützt, die zuweisbare Entitäten zurückgeben. Unter Verwendung aller oben angegebenen Informationen habe ich die folgende Funktion gefunden, die eine C-Zeichenfolge (Zeiger) erhält und die entsprechende Fortran-Zeichenfolge zurückgibt; Wenn die C-Zeichenfolge null ist, gibt sie "NULL" zurück, ähnlich wie C "(null)" in ähnlichen Fällen gedruckt:

%Vor%     
Pap 21.11.2013 12:43
quelle
2

Ich habe immer mit diesen Interoperabilitätsfunktionen zu kämpfen. Ich denke, dass Ihre Schnittstelle

deklarieren sollte %Vor%

Wenn Sie die Funktion aufrufen, übergeben Sie eine entsprechende Fortran-Zeichenvariable mit einer Länge größer oder gleich der Länge des Arrays von C-Zeichen, die Sie zurückgeben möchten.

Da Sie Intel Fortran zu haben scheinen, sehen Sie sich die mitgelieferten Codebeispiele an. Sie geben ein vollständiges Beispiel dafür.

Ich nehme an, Sie wissen, dass das, was Sie gepostet haben, nicht syntaktisch korrekt Fortran ist?

    
High Performance Mark 02.04.2012 08:25
quelle
1

In Fortran muss das Element als "character (c = char, len = 1), dimension (255)" und nicht als len = 255 deklariert werden. Dadurch wird ein Array von Zeichen der Länge eins erstellt, das Sie auf der C-Seite benötigen. Was verwirrend sein kann, ist, dass es eine Ausnahme gibt, die es Fortran erlaubt, Strings mit eindimensionalen Arrays zu vergleichen.

Sie meinen, Sie wollen eine Fortran-Prozedur von C aufrufen? Siehe dieses Beispiel: Aufruf einer FORTRAN-Subroutine von C .

BEARBEITEN: Sowohl ifort als auch gfortran sagen, dass Arrays als Funktion nicht erlaubt sind. Das macht das Zurückgeben von Zeichenfolgen als Funktionsargumente von C an Fortran schwieriger als die Verwendung einer Zeichenfolge als Argument (Beispiel in der obigen Verknüpfung) ... Sie müssen Zeiger und dann den intrinsischen c_f_pointer Fortran verwenden, um von der C-Zeichenfolge in eine Fortran-Zeichenfolge zu konvertieren , wie von haraldkl erklärt. Hier ist ein weiteres Codebeispiel:

%Vor%     
M. S. B. 02.04.2012 12:38
quelle
0

Wenn Sie die Länge der Zeichenfolge kennen, kann Paps Antwort oben erheblich vereinfacht werden:

%Vor%

Die obige Funktion akzeptiert einen C-Zeiger mit der Zeichenfolge und der Länge der Zeichenfolge und gibt eine Kopie als Fortran-Zeichenfolge zurück.

    
Ondřej Čertík 15.11.2016 20:09
quelle