EWG comes with a set of classes that help you deal with external C code in a generic and portable way. You can find those classes in the directory ${EWG}/library/runtime. If you want to distribute a wrapper generated by EWG, you don't need to provide the full EWG package alongside. The runtime library and the ${EWG}/misc directory are sufficient.
This cluster provides a generic way to deal with:
C zero terminated strings
Arrays
Pointers
EWG provides a class called EWG_MANAGED_POINTER (it is very similar and actually inspired by ISEs MANAGED_POINTER class). This class encapsulates C memory areas on a higher level than the kernel class POINTER. TODO: continue
It is important to know that instances of C structs, unions or really any C memory area are by default not first class Eiffel objects. Instead EWG creates classes who's instances can serve as companion objects. For example let's look at the following struct:
struct person
{
char* first_name;
char* last_name;
char* phone_number;
};
For this struct EWG will create a class EWG_PERSON_STRUCT_EXTERNAL, which provides low level and non-object-oriented access to the struct. EWG will also create a class called EWG_PERSON_STRUCT which uses the former class to provide the companion objects. In the next figure you can see how the relate.
The Eiffel wrapper object really only stores a reference (item) to the C struct instance. When you invoke person.first_name, where person is of type PERSON_STRUCT then the actual data will be retrieved from the C struct instance being referenced via item.
Wrappers based on pointers (EWG_MANAGED_POINTER, EWG_STRUCT and EWG_UNION) can be created to be shared or unshared, new or existing via one of the following creation procedures:
make_shared
make_unshared
make_new_shared
make_new_unshared
Note that there are two orthogonal concepts used here (see next figure).
When shared wrapper objects will be collected, their corresponding C memory will not be freed.
When unshared wrapper objects will be collected, they will also free their corresponding C memory
When creating a wrapper object with a creation procedure which contains new, then the wrapper object will itself allocate memory for the value to wrap. Use such creation procedures to create wrapper objects and the wrapped object yourself at the same time.
When creating a wrapper object with a creation procedure which does not contain new, then it will take one parameter a_item: POINTER. Use such creation procedures to create wrapper objects for C values which already exist. Pass a pointer to the C value to wrap as a_item.
TODO: Further documentation for runtime library