2016-04-06 8 views
3

Die Verwendung von Standardargumenten für Zeiger in C++ kann mit folgendem CodeStandardargumente für Zeiger in C++ und gemischter Programmierung

#include <iostream> 

void myfunc_(int var, double* arr = 0) { 
    if (arr == 0) { 
    std::cout << "1 arg" << std::endl; 
    } else { 
    std::cout << "2 arg" << std::endl; 
    } 
} 

int main() { 
    myfunc(1); 
    double *arr = new double[2]; 
    myfunc(1, arr); 
} 

in diesem Fall nachgewiesen werden, die Ausgabe des Programms ist

1 arg 
2 arg 

auf der anderen Seite, wenn ich versuche, optionale Argumente von Fortran nach C++ zu übergeben, funktioniert es nicht. Das folgende Beispiel demonstriert die sutiation Code

Die myfunc.cpp

#include <iostream> 

extern "C" void myfunc_(int var, double* arr = 0) { 
    if (arr == 0) { 
    std::cout << "1 arg" << std::endl; 
    } else { 
    std::cout << "2 arg" << std::endl; 
    } 
} 

und die Fortran Hauptprogramm

program main 
use iso_c_binding 

real*8 :: arr(2) 

call myfunc(1) 
call myfunc(1, arr) 
end program main 

und das gemischte Code (Fortran und C++) zusammengestellt werden können mit folgendem Befehl ohne Fehler

g++ -c myfunc.cpp 
gfortran -o main.x myfunc.o main.f90 -lstdc++ -lc++ 

aber das Programm druckt

2 arg 
2 arg 

in diesem Fall. Also, gibt es eine Lösung für dieses Problem? Fehle ich hier etwas? Ich denke, dass die Verwendung von Standardargumenten in der gemischten Programmierung nicht wie erwartet funktioniert, aber ich brauche an dieser Stelle einen Vorschlag.

+0

Obwohl die Antwort auf den Dupe nicht akzeptiert wird, denke ich, dass es Ihr Problem anspricht, mit anderen Worten, Sie können nicht-C-Features (wie Standardparameter) beim Kompilieren/Verknüpfen mit 'extern C' haben. Hier sind einige Möglichkeiten, es zu simulieren: http://StackOverflow.com/q/2988038/3093378 – vsoftco

+1

Verwenden von extern "C" ermöglicht dem Linker Fortran myfunc (1) Aufruf an die Funktion mit 2 Argumente zu binden. Aber nur 1 wird geliefert, große Zeit UB. Sie können dies nicht tun, verwenden Sie eine Funktion mit einem anderen Namen wie myfunc2(). –

+1

@vsoftco Ich bin nicht damit einverstanden, das zu duplizieren. Das Problem kann gelöst werden, nur der optionale Argumentteil muss in Fortran erledigt werden, dafür gibt es Unterstützung. –

Antwort

2

Wie in den Kommentaren erwähnt, können Sie keine Standardwerte von Parametern in extern "C" Funktionen haben. Sie können jedoch optionale Argumente in der Fortran-Schnittstelle der Funktion haben und nennen Sie es genau so, wie Sie wollen:

#include <iostream> 
extern "C" void myfunc(int var, double* arr) { //removed the = 0 and renamed to myfunc 
    if (arr == 0) { 
    std::cout << "1 arg" << std::endl; 
    } else { 
    std::cout << "2 arg" << std::endl; 
    } 
} 

In Fortran schaffen eine Schnittstelle Beschreibung der C (C++) Funktion:

program main 
use iso_c_binding 

interface 
    subroutine myfunc(var, arr) bind(C, name="myfunc") 
    use iso_c_binding 
    integer(c_int), value :: var 
    real(c_double), optional :: arr(*) 
    end subroutine 
end interface 

!C_double comes from iso_c_binding 
real(c_double):: arr(2) 

call myfunc(1_c_int) 
call myfunc(1_c_int, arr) 
end program main 

Der Schlüssel ist das optional Attribut in der Schnittstelle. Wenn Sie das optionale Array nicht angeben, wird stattdessen ein Nullzeiger übergeben.

Beachten Sie auch das value Attribut zum var Argument. Dies ist erforderlich, da die C++ - Funktion den Parameter als Wert akzeptiert.

Hinweis: Dies ist ein ziemlich neuer Zusatz als TS zum Fortran 2008 Standard, aber wird weitgehend unterstützt.

+0

danke für Ihre Lösung. Wird dies in g ++ und gfortran unterstützt? Hast du es getestet?Ich frage, weil, wenn ich versuche, Ihren Code mit den Befehlen zu kompilieren, die in meinem ursprünglichen Beitrag gegeben werden, beschwert sich über _myfunc Funktion (nicht definierte Symbole für Architektur ...) und kompilierte nicht. – epsilon

+0

@epsilon Ja, es wird funktionieren. Noice, dass ich _myfunc in myfunc umbenannte und dass ich 'bind (C, name =" myfunc ") benutze' Achten Sie darauf, diesen Details zu folgen oder _myfunc zu verlassen und 'bind (C, name =" _ myfunc ")' 'zu verwenden. –

+0

Ja, ich weiß, dass der Funktionsname geändert wurde. Es ist seltsam und ich verwende Ihren Code ohne jede Änderung, aber es kompiliert nicht. Ich habe an der Funktion und dem Hauptprogramm nichts geändert. Glauben Sie, dass es ein Problem mit der Compiler-Version geben könnte? – epsilon