14.3. User-defined External C types

User-defined external C classes are used for multiple purposes. C routines in external C classes implement Sather/C and C/Sather call interfaces. In addition, objects of external C types could be created and passed to or received from C. C global variables are accessed from Sather as shared attributes of external C classes.

14.3.1. Constants and C binding names

Constants are allowed in external C classes. The rules for constant initialization are the same as for constants in "regular" Sather classes.

There are two constant features of external C classes that have a special semantics. If present, the STR constant 'C_name' may be used to force a particular C declaration for an external C type. Similarly the STR constant 'C_header' may be used to specify a list of C header files that should be included in each file in which the C declaration appears.

The STR constant 'C_name' provides a C binding name for the type in which it occurs. The STR constant 'C_header' must be initialized to a space separated list of header files (the standard C notation <foo.h> is allowed). Note that if constants C_name and C_header are absent, the Sather compiler generates layouts for the external C objects. If they are present, no layouts are generated and the necessary types must be defined in the specified header files. In this case, it is the responsibility of the programmer to ensure that attribute names are exactly as the structure filed names provided by the header files.

Examples

external C class BAR is
   attr bar_attr_int:C_INT;
   attr bar_attr_float:C_FLOAT;

   -- the constructor is defined in C
   create_bar:BAR;
   -- this routine that does some processing of bar is also
   -- defined in   C
   process_bar(bar:BAR);
end;

-- create an object of type BAR by calling an external
-- C constructor
bar:BAR := BAR::create_bar;

-- now pass "bar" back to C from processing
BAR::process_bar(bar);

In this example, the Sather compiler generates the layout for the external objec BARt. The corresponding C layout and prototypes of C functions that are called from Sather are below:
typedef struct {
   int integer_field;
   float float_field;
} *C_BAR;
/* Note that C names for the type and struct fields could be
   different from the corresponding names in Sather */

C_BAR create_bar();
void process_bar(C_BAR bar);

This is a similar example, but an existing C header file is used with Sather code:
external C class BAR is
   const C_name:STR := "C_BAR";   -- C binding name for the type
   const C_header:STR := "bar.h <stdlib.h>";

   attr integer_field:C_INT;
   attr float_field:C_FLOAT;  -- the constructor is defined in C
   create_bar:BAR;
     -- this routine that does some processing of bar is also
     -- defined in C
   process_bar(bar:BAR);
end;

-- code that creates an object of type BAR by calling an external
-- C constructor and then passes the object back to C
   bar:BAR := BAR::create_bar;

      -- now pass "bar" back to C from processing
   BAR::process_bar(bar);

The C header "bar.h" contains the following:
typedef struct {
   int integer_field;
   float float_field;
} *C_BAR;
/* Note that C names for the type must be exactly as the binding C
   name specified by the C_name attribute.
   also, struct field names must be exactly the same as attribute
   names in the external C class*/

C_BAR create_bar();
void process_bar(C_BAR bar);

This creates a Sather type 'X_WIDGET' which may be used to declare variables, parameterize classes, and so forth. Furthermore, the C declaration used for variables of type 'X_WIDGET' will be 'struct XSomeWidget *'. Any generated C file containing any variable of this type will also include '<widgets.h>'
external C class X_WIDGET is
   const C_name:STR := "struct XSomeWidget *";
   const C_header:STR := "<widgets.h>";
end; -- external class X_WIDGET

14.3.2. Attributes and C structs

Attributes and C structs

Attributes may be placed in external C classes; they are interpreted as fields of a C struct. If the layout of the class is generated by Sather (C_name and C_header symbolic constants are absent), then attributes can have any names. If a C layout from a header file specified by C_header is used, attribute textual names must be exactly the same as a struct filed names from a corresponding C type. It is the responsibility of the programmer to ensure this correspondence.

Points to note

14.3.3. Shared Attributes and C globals

Global C variables may be accessed from Sather as shared attributes of external C classes. Such shared attributes must have names corresponding to those of C globals. Similar to constants, shared attributes do not contribute to the storage needed to layout the class objects.

external C class FOO is
   C_name:STR := "FOO";
   C_header:STR := "foo.h";

   shared foo:FOO:
   attr val:C_INT;

   -- this is implemented in C
   create_foo:FOO;
end;

-- accessing a global C variable
FOO::foo := FOO::create_foo;
FOO::foo.val := #(10);

#ifndef _FOO_H_
#define _FOO_H_

typedef struct {
   int val;
} *FOO;

FOO create_foo();
#endif  _FOO_H_

/* in some C file */
FOO foo;