2013-07-24 11 views
5

Ich versuche, einen Fortran-Code aufrufen c Unterprogramm zu kompilieren und verknüpfen:Aufruf C-Funktion/Unterprogramm in Fortran-Code

Fortran-Code:

program adder 
integer a,b 
a=1 
b=2 
call addnums(a,b) 
stop  
end program 

C-Code:

void addnums(int* a, int* b) 
{ 
    int c = (*a) + (*b); /* convert pointers to values, then add them */ 
    printf("sum of %i and %i is %i\n", (*a), (*b), c); 
} 

I verwendete die folgenden Befehle, um in Windows-Umgebung zu kompilieren und zu verknüpfen.

ifort -c adder.f 
cl -c addnums.c 
ifort -o add adder.obj addnums.obj 

bekomme ich folgende Fehlermeldung:

Microsoft (R) Incremental Linker Version 8.00.50727.762 
Copyright (C) Microsoft Corporation. All rights reserved. 
-out:add.exe 
-subsystem:console 
adder.obj 
addnums.obj 
adder.obj : error LNK2019: unresolved external symbol ADDNUMS referenced in function MAIN__ 
add.exe : fatal error LNK1120: 1 unresolved externals 

Bitte helfen Sie mir, dieses Problem zu beheben? Vielen Dank.

+0

Haben Sie versucht, den Funktionsnamen (dh Großbuchstaben) zu finden? –

Antwort

10

Sie müssen ein Interface-Body für die C-Funktion innerhalb des Spezifikationsteils des Fortran-Hauptprogramms bereitstellen, das dem Fortran-Compiler mitteilt, dass der Name addnums eine C-Funktion ist. Etwas wie:

INTERFACE 
    SUBROUTINE addnums(a, b) BIND(C) 
    USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_INT 
    IMPLICIT NONE 
    INTEGER(C_INT) :: a, b 
    END SUBROUTINE addnums 
END INTERFACE 

(Mit diesen Compiler auf dieser Plattform ohne spezielle Optionen der Standard Art von integer ist die gleiche wie C_INT - aber explizit über die Ganzahlart zu sein hilft Ihnen zu schützen, wenn Compiler/Plattform oder kompilieren Optionen zu ändern.

)
+0

Danke. Dein Vorschlag hat geholfen. – momba

2

Hier zwei Dinge, die ich auf Anhieb sehen kann (ich arbeite hauptsächlich mit FORTRAN77 so dass dies nicht das neueste oder beste Weg sein kann, dies zu tun):

  1. Da Ihre C-Funktion ist, gut , eine Funktion (und keine Subroutine), müssen Sie deklarieren 'addnums' als EXTERN. Fügen Sie dies Ihrem Code in Ihrem Deklarationsabschnitt hinzu.

  2. Fügen Sie dem Namen der Funktion in Ihrem C-Code einen Unterstrich hinzu. FORTRAN tut dies automatisch für seine eigenen Funktionen, nicht aber für Funktionen in anderen Sprachen. So würde die Funktion der Unterschrift seines

    void addnums_(int* a, int* b)

This page einen ziemlich guten Überblick hat C und Fortran beim Mischen. Hoffe das hat geholfen!

+1

Die moderne Art, Fortran und C zu verbinden, besteht darin, Fortran ISO_C_Binding zu verwenden. Als Teil der Fortran-Sprache ist es kompiler- und plattformunabhängig. Es vermeidet, dass Sie über Compiler-Interna Bescheid wissen müssen. Die verlinkte Seite ist veraltet. –

+0

Wenn Sie die Bindung ISO_C nicht verwenden können, deklarieren Sie die C-Routine als __stdcall, andernfalls wird standardmäßig __cdecl verwendet. Es wird Ihre Routine aufrufen und beim Beenden abstürzen. – cup

+0

Der Link zu "Diese Seite" ist unterbrochen. – Wauzl