Private data

Any variables declared in the implementation source file will, by virtue of Babel's encapsulation, be private. Special initialization procedures can be added to the built-in _load() method that is guaranteed to be called exactly once per class to set global class data -- before any user-defined methods can even be invoked. Alternatively, if private data (sometimes referred to as state) needs to be added to a FORTRAN 77 class, SIDL arrays can be used to store the data. This is certainly not the only way to implement a FORTRAN 77 class with state, but it's one that will work wherever Babel works.

The SIDL IOR keeps a pointer (i.e., a C void *) for each object in order to support private data. Like their C equivalents, each FORTRAN 77 skeleton provides two functions for accessing the private pointer. Although the pointer arguments to the methods are 64-bit integers in FORTRAN 77, the number of bits actually stored by the IOR is determined by sizeof(void *). Babel/SIDL does not provide a low level mechanism for FORTRAN 77 to allocate memory to use for the private data pointer.

The following example illustrates the process of managing private data using the automatically generated constructor subroutine, _ctor$:$


        subroutine example_withState__ctor_fi(self, exception)
        implicit none
        integer*8 self, exception
C       DO-NOT-DELETE splicer.begin(example.withState._ctor)
        integer*8 statearray, logarray, dblarray
        call sidl_opaque__array_create1d_f(2, statearray)
        call sidl_bool__array_create1d_f(3, logarray)
        call sidl_double__array_create1d_f(2, dblarray)
        if ((statearray .ne. 0) .and. (logarray .ne. 0) .and.
     $       (dblarray .ne. 0)) then
           call sidl_opaque__array_set1_f(statearray, 0, logarray)
           call sidl_opaque__array_set1_f(statearray, 1, dblarray)
        else
C          a real implementation would not leak memory like this one
           statearray = 0
        endif
        call example_withState__set_data_f(self, statearray)
C       DO-NOT-DELETE splicer.end(example.withState._ctor)
        end

Of course, it is up to the implementation to associate elements of the arrays with particular state variables. For example, element 0 of the double array could be the kinematic viscosity and element 1 the airspeed velocity of an unladen swallow. Element 0 of the boolean array could specify African (true) or European (false). The destructor implementation for this class could look something like$:$


        subroutine example_withState__dtor_fi(self, exception)
        implicit none
        integer*8 self, exception
C       DO-NOT-DELETE splicer.begin(example.withState._dtor)
        integer*8 statearray, logarray, dblarray
        call example_withState__get_data_f(self, statearray)
        if (statearray .ne. 0) then
           call sidl_opaque__array_get1_f(statearray, 0, logarray)
           call sidl_opaque__array_get1_f(statearray, 1, dblarray)
           call sidl_bool__array_deleteRef_f(logarray)
           call sidl_double__array_deleteRef_f(dblarray)
           call sidl_opaque__array_deleteRef_f(statearray)
C       the following two lines are not strictly necessary
           statearray = 0
           call example_withState__set_data_f(self, statearray)
        endif
C       DO-NOT-DELETE splicer.end(example.withState._dtor)
        end

Continuing with this example, an accessor function for the airspeed velocity of an unladen swallow could be implemented as follows$:$


        subroutine example_withState_getAirspeedVelocity_fi(
     $     self, velocity, exception)
        implicit none
        integer*8 self, exception
        real*8 velocity
C       DO-NOT-DELETE splicer.begin(example.withState.getAirspeedVelocity)
        integer*8 statearray, dblarray
        call example_withState__get_data_f(self, statearray)
        if (statearray .ne. 0) then
           call sidl_opaque__array_get1_f(statearray, 1, dblarray)
           call sidl_double__array_get1_f(dblarray, 1, velocity)
        endif
C       DO-NOT-DELETE splicer.end(example.withState.getAirspeedVelocity)
        end



babel-1.4.0
users_guide Last Modified 2008-10-16

http://www.llnl.gov/CASC/components
components@llnl.gov