Types¶
Numeric Types¶
The numeric types usually require no conversion. In this case the type map is mainly used to generate declaration code for wrappers:
type: int
fields:
c_type: int
cxx_type: int
f_type: integer(C_INT)
f_kind: C_INT
f_module:
iso_c_binding:
- C_INT
f_cast: int({f_var}, C_INT)
One case where a conversion is required is when the Fortran argument
is one type and the C++ argument is another. This may happen when an
overloaded function is generated so that a C_INT
or C_LONG
argument may be passed to a C++ function function expecting a
long
. The f_cast field is used to convert the argument to the
type expected by the C++ function.
Bool¶
The first thing to notice is that f_c_type is defined. This is
the type used in the Fortran interface for the C wrapper. The type
is logical(C_BOOL)
while f_type, the type of the Fortran
wrapper argument, is logical
.
The f_statements section describes code to add into the Fortran
wrapper to perform the conversion. c_var and f_var default to
the same value as the argument name. By setting c_local_var, a
local variable is generated for the call to the C wrapper. It will be
named SH_{f_var}
.
There is no Fortran intrinsic function to convert between default
logical
and logical(C_BOOL)
. The pre_call and
post_call sections will insert an assignment statement to allow
the compiler to do the conversion.
If a function returns a bool
result then a wrapper is always needed
to convert the result. The result section sets need_wrapper
to force the wrapper to be created. By default a function with no
argument would not need a wrapper since there will be no pre_call
or post_call code blocks. Only the C interface would be required
since Fortran could call the C function directly.
See example checkBool.
Char¶
Any C++ function which has char
or std::string
arguments or
result will create an additional C function which include additional
arguments for the length of the strings. Most Fortran compiler use
this convention when passing CHARACTER
arguments. Shroud makes
this convention explicit for three reasons:
- It allows an interface to be used. Functions with an interface will not pass the hidden, non-standard length argument, depending on compiler.
- It may pass the result of
len
and/orlen_trim
. The convention just passes the length. - Returning character argument from C to Fortran is non-portable.
Arguments with the intent(in) annotation are given the len_trim annotation. The assumption is that the trailing blanks are not part of the data but only padding. Return values and intent(out) arguments add a len annotation with the assumption that the wrapper will copy the result and blank fill the argument so it need to know the declared length.
The additional function will be named the same as the original function with the option C_bufferify_suffix appended to the end. The Fortran wrapper will use the original function name, but call the C function which accepts the length arguments.
The character type maps use the c_statements section to define code which will be inserted into the C wrapper. intent_in, intent_out, and result subsections add actions for the C wrapper. intent_in_buf, intent_out_buf, and result_buf are used for arguments with the len and len_trim annotations in the additional C wrapper.
There are occasions when the bufferify wrapper is not needed. For
example, when using char *
to pass a large buffer. It is better
to just pass the address of the argument instead of creating a copy
and appending a NULL
. The F_create_bufferify_function options
can set to false to turn off this feature.
Char¶
Ndest
is the declared length of argument dest
and Lsrc
is
the trimmed length of argument src
. These generated names must
not conflict with any other arguments. There are two ways to set the
names. First by using the options C_var_len_template and
C_var_trim_template. This can be used to control how the names are
generated for all functions if set globally or just a single function
if set in the function’s options. The other is by explicitly setting
the len and len_trim annotations which only effect a single
declaration.
The pre_call code creates space for the C strings by allocating
buffers with space for an additional character (the NULL
). The
intent(in) string copies the data and adds an explicit terminating
NULL
. The function is called then the post_call section copies
the result back into the dest
argument and deletes the scratch
space. ShroudStrCopy
is a function provided by Shroud which
copies character into the destination up to Ndest
characters, then
blank fills any remaining space.
MPI_Comm¶
MPI_Comm is provided by Shroud and serves as an example of how to wrap a non-native type. MPI provides a Fortran interface and the ability to convert MPI_comm between Fortran and C. The type map tells Shroud how to use these routines:
type: MPI_Comm
fields:
cxx_type: MPI_Comm
c_header: mpi.h
c_type: MPI_Fint
f_type: integer
f_kind: C_INT
f_c_type: integer(C_INT)
f_c_module:
iso_c_binding:
- C_INT
cxx_to_c: MPI_Comm_c2f({cxx_var})
c_to_cxx: MPI_Comm_f2c({c_var})
This mapping makes the assumption that integer
and
integer(C_INT)
are the same type.