2010-05-25 3 views
4

Возможно ли передать функцию fortran 77 в качестве указателя функции обратного вызова на C/C++? если так, как?pass fortran 77 function to C/C++

информация, которую я нашел в Интернете относится к Fortran 90 и выше, но мой унаследованный код база находится в 77.

большое спасибо

+0

Какая операционная система? –

+1

@Paul linux, 64-bit, Intel, gfortran, g ++ или icc – Anycorn

ответ

6

Если это может быть сделано в FORTRAN 77, это будет составитель и конкретная платформа. Новая привязка ISO C к Fortran 2003 обеспечивает стандартный способ смешивания Fortran и C и любого языка, который следует или может следовать соглашениям о вызовах C, например C++. Хотя формально является частью Fortran 2003, и, хотя есть очень мало компиляторов Fortran, которые полностью поддерживают полноту Fortran 2003, привязка ISO C поддерживается многочисленными компиляторами Fortran 95, включая gfortran, g95, Sun, ifort и т. Д. Поэтому я рекомендуется использовать один из этих компиляторов Fortran 95 и метод привязки ISO C, а не определять какой-либо метод для конкретного метода. Поскольку FORTRAN 77 является подмножеством Fortran 95, почему бы не скомпилировать ваш устаревший код с одним из этих компиляторов, используя Fortran 95, чтобы добавить эту новую функцию?

Я назвал процедуры Fortran из C, используя привязку ISO C, но не передал их в качестве указателей. Это должно быть возможно. Шаги:

1) вы объявляете Fortran функцию с (C атрибутом Bind),

2) вы объявляете все аргументы с использованием специальных типов, такими как целое число (c_int), которые соответствуют типам С.

шаги 1 2 & делают Fortran функцию взаимодействовать с C.

3) Вы получаете с-указатель на эту функцию Fortran с Fortran instrinsic функции «c_funloc», присваивая значение указателя указателю типа «c_funptr».

4) В коде Fortran вы объявляете подпрограмму C, с которой вы хотите передать указатель на функцию с интерфейсом, объявив его в терминах Fortran, но используя атрибут Bind (C) и совместимые типы, чтобы Компилятор Fortran знает, как использовать конвенцию C-call, что делает подпрограмму C совместимой с Fortran.

Тогда при вызове C-подпрограмме в Fortran коды, вы можете передать ему указатель на функцию, созданный на шаге 3.

UPDATE: Пример кода: Фортран основной программы «test_func_pointer» передает указатель на Функция Fortran «my_poly» в подпрограмме C «C_Func_using_Func_ptr» и получает результат от этой функции 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 

и

float C_Func_using_Func_ptr (

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

) { 

    return ((*Func_ptr) (x)); 

} 
+0

Хмм, это может быть слишком много для хранителей источников. Возможно, мне стоит рассмотреть некоторые альтернативы. Но спасибо, я буду помнить об этом (если мы, наконец, канаву 77) – Anycorn

+1

P.S. Вы можете написать оболочку Fortran 95 для вызова своих функций FORTRAN 77 и оставить функции FORTRAN 77 неизменными. Вы можете передать указатели на функции обертки, которые будут объявлены с привязкой iso c. –

Смежные вопросы