Если это можно сделать в 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 для добавления этой новой функции?
Я вызывал процедуры Фортрана из C, используя привязку ISO C, но не передавал их как указатели. Это должно быть возможно. Шаги:
1) вы объявляете функцию Фортрана с атрибутом Bind (C),
2) вы объявляете все аргументы, используя специальные типы, такие как целое число (c_int), которые соответствуют типам C.
Шаги 1 и 2 делают функцию Фортрана совместимой с C.
3) Вы получаете C-указатель на эту функцию Fortran с помощью встроенной функции Fortran "c_funloc", присваивающей значение указателя указателю типа "c_funptr".
4) В коде Fortran вы объявляете подпрограмму C, на которую вы хотите передать указатель функции через интерфейс, объявляя ее в терминах Fortran, но используя атрибут Bind (C) и совместимые типы, так что Fortran Компилятор знает, как использовать соглашение о C-вызовах - что делает процедуру C совместимой с Fortran.
Затем, когда вы вызываете подпрограмму C в коде Фортрана, вы можете передать ей указатель функции, созданный на шаге 3.
ОБНОВЛЕНИЕ: Пример кода: основная программа Fortran "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) );
}