2013-07-24 12 views
5

Ja próbuje skompilować i połączyć kod Fortran dzwoni c podprogram:Wywoływanie C funkcja/podprogram w kodzie Fortran

kod Fortran:

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

kod C:

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 użył następujących poleceń, aby skompilować i połączyć w środowisku Windows.

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

pojawia się następujący błąd:

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 

Proszę mi pomóc rozwiązać ten problem? Dzięki.

+0

Czy próbowałeś dopasować nazwę tej funkcji (np. Wszystkie znaki maksymalne)? –

Odpowiedz

10

Musisz podać treść interfejsu dla funkcji C w części specyfikacji programu głównego Fortran, która mówi kompilatorowi Fortran, że nazwa addnums jest funkcją języka C. Coś jak:

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 

(Z tych kompilatorów na tej platformie, bez specjalnych opcji domyślny rodzaj całkowitej jest taki sam jak C_INT - ale jest wyraźnie o rodzaju całkowitej pomaga chronić Cię jeśli kompilator/platforma lub kompilacji opcji zmienić.)

+0

Dzięki. Twoje sugestie pomogły. – momba

2

Oto dwie rzeczy widzę tuż nietoperza (pracuję głównie z FORTRAN77 więc nie może to być najnowszy i najlepszy sposób, aby to zrobić):

  1. Ponieważ funkcja C jest dobrze , funkcja (a nie podprogram), musisz zadeklarować "addnums" jako EXTERNAL. Dodaj to do swojego kodu w sekcji deklaracji.

    EXTERNAL addnums
  2. Dodaj podkreślenie do nazwy funkcji w swoim kodzie C. FORTRAN robi to automatycznie na swoje własne funkcje, ale nie na funkcje w innych językach. Tak, podpis z funkcji byłoby

    void addnums_(int* a, int* b)

This page ma dość dobrą wybiegiem na mieszanie C i FORTRAN. Mam nadzieję, że to pomogło!

+1

Współczesnym sposobem łączenia Fortran i C jest użycie Fortranu ISO_C_Binding. Jako część języka Fortran jest niezależny od kompilatora i platformy. Pozwala to uniknąć konieczności poznania wewnętrznych elementów kompilatora. Linkowana strona jest przestarzała. –

+0

Jeśli nie można użyć wiązania ISO_C, zadeklaruj procedurę C jako __stdcall, w przeciwnym wypadku domyślnie jest to __cdecl. Będzie wywoływał twoją rutynę i zawieszał się przy wyjściu. – cup

+0

Link do "tej strony" jest uszkodzony. – Wauzl