For Wrap
For Wrap
For Wrap
docs
tests
.gitignore
ChangeLog.md
LICENSE.txt
README.md
add_test.sh
fortwrap.py
remove_err_logs.sh
run_tests.py
README.md
FortWrap is a python script that parses Fortran 90/95/200X source files and generates wrapper code for interfacing with the
original Fortran code from C++. FortWrap is intended to be used with Fortran code that takes an object oriented approach
and makes use of Fortran derived types. The resulting wrapper code provides a C++ interface that wraps the Fortran derived
types with C++ "proxy classes".
Currently, FortWrap is targetted at the gfortran compiler, but the generated C++ code should work with any C++ compiler,
including g++.
Features
Fortran derived types wrapped in C++ proxy classes
Experimental support for polymorphism (CLASS variables)
Arrays wrapped with C++ vectors
Support for optional arguments
Support for wrapping procedure pointers
Support for string arguments
Fortran doxygen comments transferred to C++ header files
Name mangling support for gfortran compiler
Wrappers respect Fortran public/private statements
Generated code can be re-wrapped with swig -c++
Running FortWrap
fortwrap.py is a standalone executable python script that may be run using either python fortwrap.py [args] or
fortwrap.py [args] . Use fortwrap.py ‐h to print usage information.
Documentation
Refer to the documentation at docs/manual.md . The tests directory provides working examples of most of the main
FortWrap features.
To manually run a test, first make sure the compiler specified in tests/Tests.mk is valid. Then change to a test directory, for
example, tests/arrays. Execute ../../fortwrap.py ‐g ‐d wrap to generate the C++ wrapper code (some tests, for example
c_arrays, require different FortWrap options, which are defined in run_tests.py). Then execute make to build the simple test
program in that directory, prog.cpp.
Notes
The internals of FortWrap are in a stable state and have been used successfully to wrap very large Fortran projects (~40,000
lines of code). However, FortWrap is not intended to wrap all Fortran constructs. In particular, FortWrap is geared towards
wrapping derived types and procedures that operate on them. FortWrap is not intended to wrap legacy code and should not
be used with Fortran 77 code. For more details regarding the Fortran constructs that FortWrap is set up to wrap, refer to the
documentation and the tests directory.
Examples
For simplicity, some of the examples below are not shown with derived types. When the first argument is not a derived type,
FortWrap by default wraps the routine as a static method of the special "utility class" FortFuncs (this can be overriden with
the ‐‐global option).
Derived Types
" ctor " procedures are wrapped as C++ constructors. Multiple constructors are supported. " dtor " procedures are
automatically called by the C++ destructor. For example:
MODULE m
TYPE Object
REAL, ALLOCATABLE :: x(:)
END TYPE Object
CONTAINS
SUBROUTINE default_ctor(o,n)
TYPE(Object) :: o
INTEGER, INTENT(in) :: n
ALLOCATE(o%x(n))
END SUBROUTINE default_ctor
SUBROUTINE value_ctor(o,n,val)
TYPE(Object) :: o
INTEGER, INTENT(in) :: n
SUBROUTINE object_dtor(o)
TYPE(Object) :: o
IF(ALLOCATED(o%x)) DEALLOCATE(o%x)
END SUBROUTINE object_dtor
END MODULE m
Object(int n);
Object(int n, float val);
The Fortran destructor object_dtor will automatically be called by the C++ destructor.
Arrays
FUNCTION inner_prod(n,a,b) RESULT(y)
INTEGER, INTENT(in) :: n, a(n), b(n)
INTEGER :: y
y = DOT_PRODUCT(a,b)
END FUNCTION inner_prod
generates a method of the "utility class" FortFuncs (the utility class is used to wrap functions that do not operate on a
derived type):
Optional Arguments
FUNCTION add_mixed(a,b,c,d) RESULT(y)
INTEGER, INTENT(in) :: a,b
INTEGER, INTENT(in), OPTIONAL :: c,d
INTEGER :: y
y = a+b
IF (PRESENT(c)) y = y + c
IF (PRESENT(d)) y = y + d
END FUNCTION add_mixed
Note that a and b use pass-by-value since they are not optional. The optional arguments c and d use pass-by-reference.
Passing NULL (which is the default) indicates that the argument is not provided.
These wrappers are particularly powerful when using swig with ‐c++ ‐keyword , since the optional parameters can then be
passed by keyword in the target language
Known Issues
Scalar character arguments not wrapped correctly (generated code won't compile)
Old-style dummy argument definitions that do not include :: are not recognized
Enumerators are not wrapped correctly if some names within a set are made private