Whenever we write an interface with a C function or struct, we first look at the documentation for that function. Ideally, the C library you work with will be well documented. However, this isn’t always the case, and sometimes we need to look at the C source code to see how the function is defined there.
Our first step is to write a Fortran interface with the C struct ipaddr in the libdill library. This is the first ingredient we need to get before implementing the ipaddr_local (server) and ipaddr_remote (client) functions. A struct in C is analogous to a derived type in Fortran (see chapter 8)–an arbitrary data structure with components of built-in or other data types. For the most part, they have a similar syntax and behavior.
Although the functions ipaddr_local and ipaddr_remote are described in the documentation, the ipaddr struct that they use as an argument isn’t. To understand how to write a Fortran interface with this struct, we need to look inside the libdill header file. If you installed libdill following the instructions in the previous subsection, you’ll find the file here: libdill-2.14/libdill.h. The relevant snippet that gives the definition of the ipaddr struct in libdill.h is
struct dill_ipaddr {char _[32];};
Although it may seem a bit cryptic at first, this is a relatively simple struct. It has only one component, an array of 32 characters called _ (underscore). Our task is to define a Fortran derived type that will match this struct. The following listing shows a working Fortran interface, defined in a new module.
Listing 11.1 A Fortran interface with the ipaddr struct
module mod_dill
use iso_c_binding, only: c_char ❶
implicit none
private
public :: ipaddr
type, bind(c, name='dill_ipaddr') :: ipaddr ❷
character(c_char) :: address(32) ❸
end type ipaddr ❹
end module mod_dill
❶ Imports the C character type kind parameter from iso_c_binding
❷ Defines a new derived type and binds its name to a C equivalent struct
❸ This type has only one component, an array of 32 characters.
Quite a few things are going on here. First, like any other Fortran code that we aim to reuse, we define this derived type in a module. I chose mod_dill as the module name–mod_ as a prefix following my preferred convention for naming modules, and dill because, well, we’re writing an interface with libdill (the dill library).
Second, we import c_char from the iso_c_binding module. Like iso_fortran _env, iso_c_binding is a built-in module that’s specified by the standard and provided by the compiler. c_char is a type kind parameter, just like int64 and real64 from iso_fortran_env. Its purpose is to provide the exact type kind to interface with the character in the companion C compiler. A companion C compiler is simply the C compiler compatible with your Fortran compiler, and typically from the same vendor. For example, the companion C compiler to gfortran is gcc, and the companion C compiler to ifort (Intel Fortran) is icc (Intel C compiler).
Finally, we get to our derived type, ipaddr. The opening line of the type definition has a new attribute, bind(). This attribute states that this derived type is meant to bind to an existing C struct, whose name is specified as a keyword argument, name. If this argument is omitted, the compiler will use the name of the derived type (in all lowercase) as the name of the matching C struct. Like its C counterpart, this derived type has only one component, an array of 32 characters. This is where we use the c_char as a type kind parameter to declare the component in the Fortran implementation.
Recall that the original C struct has a component named _ (underscore). Ideally we’d match C variable names exactly in our Fortran interface, for clarity. Although Fortran allows underscores in variable, procedure, and module names, it doesn’t allow using one as the first or the only character in a name. To work around this restriction, we can name our component something meaningful. I chose address, as this component will internally store the address and port components of an IP address.
C has characters, which are always of length 1. Multicharacter strings are represented as arrays of characters. A string in C is terminated with a null character, '\0'. This is an important detail to be mindful of as we exchange character strings between our Fortran code and the C functions.
Figure 11.4 illustrates the interface between the Fortran derived type and a C struct.

Figure 11.4 Mapping a C struct to a Fortran derived type
The ipaddr struct in libdill is used strictly internally. We won’t write data to its component directly, and we’ll only manipulate it through functions ipaddr_local and ipaddr_remote.
You can now compile this module:
gfortran -c mod_dill.f90
The -c option means “compile only, do not link.” The compiler will produce the compiled module file mod_dill.mod and the binary object file mod_dill.o. Even though we defined a derived type that binds to a C struct, no C code or compiled object came into the picture. This module doesn’t do anything useful yet, as it just defines a simple derived type to interface with a C struct. Let’s see how we can use this type to open a new connection.