Let us consider a C++/Fortran90 interface for the SEPlib90 data
structure. The IGF90Space class provides an encapsulation of the
SEPlib90 header information. The following lines of code show part of
the IGF90Space class definition:
typedef void* HANDLE;
#define OPAQUE_SIZE 1024;
extern "C" sep90_reed_(const char * , int *, HANDLE);
class IGF90Space: public HCL_VectorSpace {
protected:
HANDLE opaque_f90_handle; // pointer to Fortran90 data structure;
public:
IGF90Space();
IGF90Space(char *tag);
~IGF90Space();
... // some other constructors and virtual member functions
HANDLE GetOpaque();
};
IGF90Space::IGF90Space(){
opaque_f90_handle = new char[OPAQUE_SIZE];
}
IGF90Space::IGF90Space(char *tag){
opaque_f90_handle = new char[OPAQUE_SIZE];
int length = strlen(tag);
sep90_reed_( tag, &length , opaque_f90_handle );
}
IGF90Space::~IGF90Space(){
delete opaque_f90_handle;
}
HANDLE IGF90Space::GetOpaque() const {
return(opaque_f90_handle);
}
The IGF90Space class is composed of an opaque_f90_handle
pointer to the Fortran90 data structure. The opaque_f90_handle
pointer is used to pass the Fortran90 data structure in the C++ world.
The constructor IGFSpace90(char *tag) initializes an IGF90Space
object by reading the header information of the SEPlib90 data
structure from disk, which is done by the sep90_reed Fortran90
subroutine. Because of class encapsulation, access to the
opaque_f90_handle pointer is obtained only through the
GetOpaque() member function.
The Fortran90 subroutine sep90_reed provides a wrapping layer
to the sep_reed _mod module. The Fortran90 sep_reed_mod
module is described in this report by Clapp and
Crawley 1996. Some Fortran90 compilers use
the ``$'' sign to name subroutines defined within modules. The
direct call of Fortran90 subroutines that are within a module will
require the inclusion of the ``$'' sign in the C++ extern call. Some
compilers will only allow the use of the ``$'' sign if one uses
special compiler flags. We opted not to use these flags, but used
another layer of Fortran90 wrapping in order to be completely
portable. The next lines of code show the wrapper file for the Fortran90
sep_reed_mod module:
subroutine sep90_reed(tag,length,sepdata)
use sep_reed_mod
integer length
character*(length) tag
type (sep_90), pointer ::sepdata
character(len=length) :: newtag
newtag = tag
call init_vars(sepdata)
!read in only the headers
call sep_reed(newtag,sepdata,header_only=.true.)
return
end subroutine