Pass for tran 77 function in C / C ++

Is it possible to pass a fortran 77 function as a pointer to a callback function in C / C ++? if so, how?

the information i found on the internet is for fortran 90 and above, but my base code base is at 77.

many thanks

+4
source share
1 answer

If this can be done in FORTRAN 77, it will be a compiler and platform. The new binding of ISO C to Fortran 2003 provides a standard way to mix Fortran and C and any language that follows or can follow C calling conventions, such as C ++. Although formally part of Fortran 2003, and although there are very few Fortran compilers that fully support Fortran 2003, the ISO C binding is supported by numerous Fortran 95 compilers, including gfortran, g95, Sun, ifort, etc. Therefore, I recommend that you use one of these Fortran 95 compilers and the ISO C binding method, rather than defining any method for a particular method. Since FORTRAN 77 is a subset of Fortran 95, why not compile your old code with one of these compilers, using Fortran 95 to add this new feature?

I named Fortran procedures from C using the ISO C binding, but did not pass them as pointers. It should be possible. Steps:

1) you declare a Fortran function with the Bind (C) attribute,

2) you declare all arguments using special types, such as integer (c_int), which correspond to C types.

Steps 1 and 2 make the Fortran function compatible with C.

3) You get a C-pointer to this Fortran function using the Fortran built-in function "c_funloc", assigning a pointer value to a pointer of type "c_funptr".

4) In Fortran code, you declare a C routine that you want to pass to a function pointer with an interface, declaring it in Fortran terms, but using the Bind (C) attribute and compatible types so that the Fortran compiler knows how to use the C-call convention - creating a routine C compatible with Fortran.

Then, when you call the C procedure in Fortran code, you can pass it a pointer to the function you created in step 3.

UPDATE: Code example: Fortran main program "test_func_pointer" passes the pointer to the Fortran function "my_poly" to the C routine "C_Func_using_Func_ptr" and returns the result from this 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 

and

 float C_Func_using_Func_ptr ( float x, float (*Func_ptr) (float y) ) { return ( (*Func_ptr) (x) ); } 
+6
source

Source: https://habr.com/ru/post/1310823/


All Articles