2010-05-25 6 views
4

Est-il possible de passer la fonction fortran 77 comme un pointeur de fonction de rappel à C/C++? si oui, comment?passer la fonction fortran 77 à C/C++

informations que je trouve sur le web se rapporte à Fortran 90 et au-dessus, mais ma base de code existant est en 77.

merci beaucoup

+0

Quel système d'exploitation? –

+1

@Paul linux, 64 bits, Intel, gfortran, g ++ ou icc – Anycorn

Répondre

6

Si cela peut être fait en FORTRAN 77, il sera compilateur et plate-forme spécifique. La nouvelle liaison ISO C de Fortran 2003 fournit une manière standard de mélanger Fortran et C, et tout langage qui suit ou peut suivre les conventions d'appel de C, tel que C++. Bien que formellement une partie de Fortran 2003, et alors qu'il y a extrêmement peu de compilateurs Fortran qui supportent entièrement l'intégralité de Fortran 2003, la liaison ISO C est supportée par de nombreux compilateurs Fortran 95, y compris gfortran, g95, Sun, ifort, etc. recommande d'utiliser l'un de ces compilateurs Fortran 95 et la méthode ISO C Binding plutôt que de trouver une méthode pour une méthode particulière. Puisque FORTRAN 77 est un sous-ensemble de Fortran 95, pourquoi ne pas compiler votre code hérité avec l'un de ces compilateurs, en utilisant Fortran 95 pour ajouter cette nouvelle fonctionnalité?

J'ai appelé les procédures Fortran de C en utilisant la liaison ISO C, mais je ne les ai pas passées comme pointeurs. Cela devrait être possible. Les étapes sont les suivantes:

1) vous déclarer la fonction Fortran avec le Bind (C) attribut,

2) on déclare tous les arguments à l'aide de types spéciaux, tels que nombre entier (c_int), qui correspondent aux types de C.

étapes 1 & 2 de vous faire obtenir un pointeur de C à cette fonction Fortran avec la fonction Fortran intrinsèque « c_funloc », en attribuant la valeur du pointeur de la fonction Fortran interopérable avec C.

3) à un pointeur de type "c_funptr". 4) Dans le code Fortran, vous déclarez la routine C à laquelle vous voulez passer le pointeur de fonction avec une interface, en le déclarant en termes Fortran, mais en utilisant l'attribut Bind (C) et les types interopérables pour que le Le compilateur Fortran sait utiliser la convention d'appel C - rendant la routine C interopérable avec Fortran.

Quand vous appelez la routine C dans le code Fortran, vous pouvez passer le pointeur de la fonction créée à l'étape 3.

MISE À JOUR: Exemple de code: Le programme principal Fortran « test_func_pointer » passe un pointeur vers la Fortran fonction "my_poly" à la routine C "C_Func_using_Func_ptr" et reçoit le résultat de cette fonction C.

module func_pointer_mod 

    use, intrinsic :: iso_c_binding 

    implicit none 

    interface C_func_interface 

     function C_Func_using_Func_ptr (x, Func_ptr) bind (C, name="C_Func_using_Func_ptr") 

     import 

     real (c_float) :: C_Func_using_Func_ptr 
     real (c_float), VALUE, intent (in) :: x 
     type (c_funptr), VALUE, intent (in) :: Func_ptr 

     end function C_Func_using_Func_ptr 

    end interface C_func_interface 


contains 

    function my_poly (x) bind (C, name="my_poly") 

     real (c_float) :: my_poly 
     real (c_float), VALUE, intent (in) :: x 

     my_poly = 2.0 * x**2 + 3.0 * x + 5.0 

     return 

    end function my_poly 

end module func_pointer_mod 


program test_func_pointer 

    use, intrinsic :: iso_c_binding 

    use func_pointer_mod 

    implicit none 

    type (c_funptr) :: C_func_ptr 

    C_func_ptr = c_funloc (my_poly) 

    write (*, *) C_Func_using_Func_ptr (2.5_c_float, C_func_ptr) 

    stop 

end program test_func_pointer 

et

float C_Func_using_Func_ptr (

    float x, 
    float (*Func_ptr) (float y) 

) { 

    return ((*Func_ptr) (x)); 

} 
+0

hmm, cela peut-être trop pour les gardiens de la source. Peut-être que je devrais envisager quelques alternatives. Mais merci, je vais garder cela à l'esprit (si nous avons finalement fossé 77) – Anycorn

+1

P.S. Vous pouvez écrire des wrappers Fortran 95 pour appeler vos fonctions FORTRAN 77 et laisser les fonctions FORTRAN 77 inchangées. Vous pouvez passer des pointeurs aux fonctions wrapper, qui seront déclarées avec la liaison iso c. –

Questions connexes