Calling a C function with various types and arguments from Fortran

To call a variadic C function such as printf from Fortran that can take an arbitrary number of arguments of various types, you can create Fortran interfaces for various sets of arguments, but the number of interfaces needed will grow exponentially with the number of arguments allowed. One could write a program to create such interfaces. Is there another approach? Here is Fortran code with interfaces to printf to print an integer or a string that works with gfortran, ifort, and nvfortran.

program call_printf
use iso_c_binding, only: c_int, c_char, c_null_char, c_new_line
interface
function print_string(fmt,s) result(ierr) bind(c,name="printf")
! Use C printf() to print string with format fmt
import c_char
character(c_char) :: fmt(*), s(*)
end function print_string
end interface
interface
function print_integer(fmt,i) result(ierr) bind(c,name="printf")
! Use C printf() to print integer with format fmt
import c_char, c_int
character(c_char) :: fmt(*)
integer(kind=c_int), intent(in), value :: i
end function print_integer
end interface
integer :: ierr
ierr = print_string("string is %s" // c_new_line // c_null_char, &
                    "abc" // c_null_char)
ierr = print_integer("int is %d" // c_new_line // c_null_char, 42_c_int)
end program call_printf
! output:
! string is abc
! int is 42

That is indeed a problem. In GTK (written in C), to ease language bindings they try to propose for most variadic functions a special version, with a v appended, that uses generally a pointer toward an array. For example:

GtkTreeStore*
gtk_tree_store_new (
  gint n_columns,
  ...
)

and

GtkTreeStore*
gtk_tree_store_newv (
  gint n_columns,
  GType* types
)

where types is “an array of GType types for the columns, from first to last.”

See https://docs.gtk.org/gtk4/ctor.TreeStore.new.html
and https://docs.gtk.org/gtk4/ctor.TreeStore.newv.html

See also that discussion for a J3 proposal:

The standard for Fortran states, “The C language allows specification of a C function that can take a variable number of arguments (ISO/IEC 9899:2018, 7.16). This document does not provide a mechanism for Fortran procedures to interoperate with such C functions.”

Generally there isn’t a good approach for C “varargs” functions.

1 Like

Unless you plan to actually call it for all of those combinations, why would you declare all of them? In practice you will only need as many interfaces as you have calls. :wink: