Mercurial > octave
changeset 32808:b81aef2c6d82 stable
doc: Expand on documentation of interfacing to Fortran code.
* doc/interpreter/external.txi: Remove recommendation of obsolete macro. Add
documentation for related preprocessor macros.
* examples/code/fortrandemo.cc: Don't use obsolete macro in example.
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Mon, 22 Jan 2024 19:16:08 +0100 |
parents | 07ff21a1dd1c |
children | aeb8f8438dd5 504257a76eea |
files | doc/interpreter/external.txi examples/code/fortrandemo.cc |
diffstat | 2 files changed, 92 insertions(+), 21 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/interpreter/external.txi Mon Jan 22 11:39:45 2024 +0100 +++ b/doc/interpreter/external.txi Mon Jan 22 19:16:08 2024 +0100 @@ -336,7 +336,7 @@ of rows and columns in the matrix. @end deftypefn -@deftypefn {Method} {T*} fortran_vec () +@deftypefn {Method} {T *} fortran_vec () This method returns a pointer to the underlying data of the matrix or array so that it can be manipulated directly, either within Octave or by an external library. @@ -989,10 +989,93 @@ @end group @end example -Calling Fortran code, however, can pose more difficulties. This is due to -differences in the manner in which compilers treat the linking of Fortran code -with C or C++ code. Octave supplies several macros that allow consistent -behavior across a number of compilers. +When calling functions that are implemented in Fortran code, some pecularities +have to be taken into account. Symbol names in Fortran are case-insensitive, +and depending on the used Fortran compiler, function names are either exported +with all lower-case or with all upper-case characters. Additionally, some +compilers append none, one or two underscores "@code{_}" at the end of +exported function names. This is called "name-mangling". + +Octave supplies macros that allow writing code that automatically handles the +name-mangling for a number of different Fortran compilers. These macros are +@code{F77_FUNC} and @code{F77_FUNC_}. The former should be used for Fortran +functions that do not contain any underscores in their name. The latter should +be used for Fortran functions with underscores in their names. Both macros +take two arguments: The first is the Fortran function name in all lower-case +characters. The second is the same Fortran function name in all upper-case +characters. + +Additionally to the name-mangling, different compilers are using different +calling conventions for some types. Octave defines the following preprocessor +macros to allow writing code that can be used with different Fortran calling +conventions. + +Note that we don't attempt to handle Fortran functions, we always use +subroutine wrappers for them and pass the return value as an extra argument. + +Use the following macros to pass character strings from C to Fortran: + +@example +@group + F77_CHAR_ARG(x) + F77_CONST_CHAR_ARG(x) + F77_CXX_STRING_ARG(x) + F77_CHAR_ARG_LEN(l) + F77_CHAR_ARG_DECL + F77_CONST_CHAR_ARG_DECL + F77_CHAR_ARG_LEN_DECL +@end group +@end example + +Use the following macros to write C-language functions that accept +Fortran-style character strings: + +@example +@group + F77_CHAR_ARG_DEF(s, len) + F77_CONST_CHAR_ARG_DEF(s, len) + F77_CHAR_ARG_LEN_DEF(len) + F77_CHAR_ARG_USE(s) + F77_CHAR_ARG_LEN_USE(s, len) +@end group +@end example + +Use the following macros for Fortran types in C++ code: + +@table @code +@item F77_INT4 +Equivalent to Fortran @code{INTEGER*4} type + +@item F77_DBLE +Equivalent to Fortran @code{DOUBLE PRECISION} type + +@item F77_REAL +Equivalent to Fortran @code{REAL} type + +@item F77_CMPLX +Equivalent to Fortran @code{COMPLEX} type + +@item F77_DBLE_CMPLX +Equivalent to Fortran @code{DOUBLE COMPLEX} type + +@item F77_LOGICAL +Equivalent to Fortran @code{LOGICAL} type + +@item F77_RET_T +Return type of a C++ function that acts like a Fortran subroutine. +@end table + +Use the following macros to return from C-language functions that are supposed +to act like Fortran subroutines. @code{F77_NORETURN} is intended to be used as +the last statement of such a function that has been tagged with a +@qcode{"noreturn"} attribute. + +@example +@group + F77_RETURN(retval) + F77_NORETURN(retval) +@end group +@end example The underlying Fortran code should use the @code{XSTOPX} function to replace the Fortran @code{STOP} function. @code{XSTOPX} uses the Octave exception @@ -1000,20 +1083,8 @@ Octave supplies its own replacement @sc{blas} @code{XERBLA} function, which uses @code{XSTOPX}. -If the code calls @code{XSTOPX}, then the @w{@code{F77_XFCN}} macro should be -used to call the underlying Fortran function. The Fortran exception state can -then be checked with the global variable @code{f77_exception_encountered}. If -@code{XSTOPX} will not be called, then the @w{@code{F77_FCN}} macro should be -used instead to call the Fortran code. - -There is no great harm in using @w{@code{F77_XFCN}} in all cases, except that -for Fortran code that is short running and executes a large number of times, -there is potentially an overhead in doing so. However, if @w{@code{F77_FCN}} -is used with code that calls @code{XSTOP}, Octave can generate a segmentation -fault. - -An example of the inclusion of a Fortran function in an oct-file is given in -the following example, where the C++ wrapper is +The following example shows the inclusion of a Fortran function in an oct-file, +where the C++ wrapper is @example @EXAMPLEFILE(fortrandemo.cc)
--- a/examples/code/fortrandemo.cc Mon Jan 22 11:39:45 2024 +0100 +++ b/examples/code/fortrandemo.cc Mon Jan 22 19:16:08 2024 +0100 @@ -20,8 +20,8 @@ OCTAVE_LOCAL_BUFFER (char, ctmp, 128); - F77_XFCN (fortransub, FORTRANSUB, - (na, av, ctmp F77_CHAR_ARG_LEN (128))); + F77_FUNC (fortransub, FORTRANSUB) + (na, av, ctmp F77_CHAR_ARG_LEN (128)); return ovl (a, std::string (ctmp)); }