From: gary@intrepid.intrepid.com (Gary Funck)
Newsgroups: comp.lang.ada
Subject: Ada Bindings & Pragma Portability
Date: 30 Sep 92 16:05:42 GMT
Article-I.D.: intrepid.1992Sep30.160542.19027
Organization: Intrepid Technology, Inc.

Dear Ada Experts,

While completing the development of a multi-platform, multi-vendor set
of Ada bindings to a C library of relational database routines, I've
come upon several areas, where the bindings strongly depend on the
compiler's data layout policy, or its method for binding to
object names in the target language.  I'm hoping that you can shed
some light on the best methods to achieve portability (with the
minimum amount of work, of course).

As further background, the compiler vendors of choice for now are
(alphabetically) Alsys, Telesoft, and Verdix, although the intent
of the bindings package is that it can port across most compiler
vendors and computer platforms.

The bindings problems encoutered so far, are:

1. Linkage to C routines.  Most vendors offer a
"pragma interface(C, routine_name);" facitility, although at one point
in time, it seemed that Telesoft required you to say
"pragma interface(UNIX, routine_name);". Is this still the case?

Most vendors seem to follow the rule that "routine_name" will be forced
to lower case (and prefixed with "_" if that's the C naming convention).
Is this a valid assumption?

Some vendors (all of the 3 above?) offer a facility for specifying
the exteranl symbol name explicitly, using a pragma of the form:
pragma interface_name(routine_name, "<external name>");  Is this
generally supported?  (though, the name may have to be prefixed
with literal defined in a "LANGUAGE" package ... see below).

2. Overlay of C records.  The Ada bindings package has the requirement
to offer programmer visibility to various records used to communicate
data to the underlying C library; therefore, the Ada representation
of the record and the C representation must be in sync.  The records
themselves are relatively ucomplicated, consisting mainly of
16 bit integers, 32 bit integers, 32 bit address, fixed length character
strings (with an even number of characters).

Although representation clauses are the indisputably correct way to go,
I'm hoping that the bindings package can depend on the underlying compiler
to lay out a record declaration in a "natural order". Already there
are three different packages, one for each vendor, and the combintorial
explosion caused by having a different package for each
(vendor,host machine) pair would cause significant product build
headaches.

As an example,

    type data_record is record
	rec_tag:  smallint;
	value1:   int;
	value2:   address;
	value3:   array (1..10) of char;
	end record;

where smallint has been defined to be a 16 bit integer, and int 32 bits.

Is it reasonable to assume that the compiler laid the fields out in
the order given, and used the host machine's convention for laying
out the data? 

3. References to external data objects.  The bindings package needs
to access a couple of global variables that return status codes afer
various database operations.  The first approach used was to say
something along these lines:

    SQLCODE: INT;
    pragma interface_name(SQLCODE, "sqlcode");

This works with the Verdix compiler, but apparently is not supported
by Alsys.  To be truthful, it didn't work on all platforms with the
Verdix compiler; the declaration had to be augmented as follows:

    SQLCODE: INT;
    pragma interface_name(SQLCODE, LANGUAGE.PREFIX & "sqlcode");

Given the problems with interfacing directly to the data value, it looks
as if we'll need to call C functions instead, that return the status
values.  Fortunately, the Ada programs don't modify the data values,
otherwise the "transparency" of the function is lost (ie,
a function of the form "set_sqlcode(value);" would be called instead
of the more natural syntax: "sqlcode := value;).

Is it generally necessary to write data access functions in C (or
FORTRAN, etc) to offer access from an Ada program to global data values
in the "foreign language", or is there some other "reasonably"
portable approach?

                              - - -

Perhaps my reluctance to grapple with representation clauses and
data access functions, and techniques (such as generics, protected
records) that offer a "higher level" view of the C interfaces has
overly constrained the problem.  However compatibility issues and
limited development time prevent a complete rework of the Ada bindings
at this time.

With this in mind, I'd appreciate your insight, experience and recommendations
on how to approach the development of a portable set of Ada bindings.
If you can recommend references to guidelines and procedures (even those
that take the "high road") for developing Ada bindings to libraries
written in other languages (ie, C), they'd be greatly appreciated.

thanks,

- Gary

PS: I hope Ada 9X (or some other effort) will standardize the pragmas
and other methods used provide interfaces between Ada and
(commonly used) non-Ada libraries.
-- 
| Gary Funck  		    gary@intrepid.com  [uunet!uupsi!intrepid!gary]
| Intrepid Technology Inc., Mountain View CA (415) 964-8135
--