IDL
IDL is the Interface Definition Language, whose syntax is defined as
part of the CORBA(Common Object Request Broker)
standard.
Dave Quarrie of LBL has modifed the IDL compiler to generate interface code from
C++ or Fortran 90. David has supplied most of the commentary below.
For BaBar, the interface to Farfalla is described in an
IDL input file.
The colias.idl file describes the existing BaBar data model. It
cheats a bit since F_Node should be in module farfalla instead of
colias, but my code generator expects that for module, class there
is a .hh file of the form "module/class.hh", and that doesn't exist
within farfalla for F_Node. It was just easier for me to add the
relevant .hh file to colias.
The compiler then generates
90% of the F-90 code is interface declarations - i.e. no real
machine code is generated. All it does is to allow type checking
etc. and tell the F-90 client what the C glue is actually going to
do.
The 10% that is actually code is routines to copy data (attributes
in the IDL terminology) between a F-90 structure and a C++ object
(and v.v.) for each interface, and routines to perform typecasting
for F-90 structures (F-90 doesn't have a way of typecasting a
pointer to a structure to become a pointer to another structure,
something that is valid if the structures actually correspond to C++
objects that share an inheritance relationship.
The .hh file is the interface definition file and
has to be included in client implementation files. For the
ccstub.hh file, it's the declaration of the C (not C++ actually)
routines that are defined in the
These are glue
routines that forward the calls to the appropriate C++ object
function members.
The .hh file includes a bunch of other .hh files
(e.g. colias/F_Node.hh). These .hh files are the interface
definitions for the classes. Somewhat confusingly, in C++ you have
to specify both the public and private interface in the .hh file -
pretty silly really.
Automatic Generation of Farfalla I/O
Jim: I was imagining
someone at FNAL say adding automatic generation of I/O
routines to Farfalla, or emitting them via extensions to the
IDL compiler...
Dave:
Sounds good to me. I'm happy to go along with that concept. One
problem with the automatic generation of the I/O routines from the
IDL interface is that that interface only specifies the public
interface via accessor functions. It says nothing at all about the
internal data members, only how they are accessed. Thus it doesn't
deal with any bit packing or other fancy operations (e.g. you might
return the module & channel ids as longs, but they might in fact be
packed fields within the data member. IDL won't specify that.
Automatic eligibility for I/O
Jim: By the way, to the extent that Farfalla nodes have nicely
hidden dynamic allocation/deallocation from such as myself,
I'm surprised one wouldn't try to have classes inherit that
from them, rather than creating the objects from scratch and
then copying them into nodes later? Perhaps I am in the old
ZEBRA philosophy of everything is eligible to be written
unless forcibly dropped...
Dave:
Basically, that's the approach we're sort of taking. Most of the
"temporary" objects do in fact inherit from F_Node (actually
DATColiasNode) so they are elligable for output.
Example of Fortran 90 Access to Farfalla data
Here's a trivial F-90 subroutine that accesses data within
an event:
SUBROUTINE f90_event( handle )
USE colias_module
IMPLICIT NONE
TYPE(F_Node_handle), INTENT(IN) :: handle
TYPE(F_Node_handle), POINTER :: rawNode
TYPE(F_Node_handle), POINTER :: svtNode
TYPE(DATSVTRawNode_handle), POINTER :: svtRaw
TYPE(DATSVTDigi_handle), POINTER :: aDigi
TYPE(DATSVTDigi) :: bDigi
INTEGER :: nDigis, index
rawNode => F_Node_getChild( handle, DATRawDataNode_type, 0 )
svtNode => F_Node_getChild( rawNode, DATSVTRawNode_type, 0 )
svtRaw => DATSVTRawNode_from_F_Node( svtNode )
nDigis = DATSVTRawNode_nDigis( svtRaw )
PRINT *,"nDigis=",nDigis
DO index = 1, nDigis
aDigi => DATSVTRawNode_digi( svtRaw, index-1 )
PRINT *,"Digi ", index
PRINT *," aDigi.channel ", DATSVTDigi_channel( aDigi )
CALL DATSVTDigi_toF90( aDigi, bDigi )
PRINT *," bDigi.channel ", bDigi % channel
END DO
RETURN
END
Jim Linnemann