This chapter describes the .NET code generation in more detail. The .NET wrapper consists of a native DLL and a managed assembly. The source code for both the native DLL and the managed assembly is generated with a self-written code generator program. The code generator reads a bunch of XML files and transforms this into wrapper code. The native DLL is a flattened-out representation of the nGI class hierarchy. Functions from this DLL can be called by the managed assembly via DllImport statements.
XML interface definition
For each class, one XML interface definition file has to be written. This interface definition spells out the details of the wrapped classes: the name, the constructors, properties and methods, their parameters etc. The wrapper generator reads in the interface definition and builds an object tree out of them. This tree is then walked by the wrapper generator in order to generate source code.

The <binary_operator> element is used to specify binary operators. It
has name, type and optional qualifier attributes, but no child
elements. The name attribute specifies the operator name and the
type attribute specifies the return type. For more information about
the type attribute, see the <type> element. If used, the qualifier
attribute can either contain the string const or an empty string. If
the qualifier attribute is missing, the empty string is used by
default.
The <constructor> element is used to specify a constructor of a class.
It is a child of the <class> element. It has no attributes but one or
more <parameter> child elements.
The <copy_constructor> element is used to specify a copy constructor
of a class. It is a child of the <class> element. It has no attributes
or child elements.
The <class> element specifies a class. The <class> element is a
child of the <file> element. A <class> element can have
constructors, operators, properties, methods, events and some other
aspects. The <class> element has a name attribute. Class
constructors are specified with the <default_constructor>,
<constructor> and <copy_constructor> child elements. Operators are
specified with the <unary_operator> and <binary_operator> child
elements. Properties are specified with the <property> child elements.
Methods are specified with the <method> and <static_method> child
elements. Events are specified with the <event> child element. If the
specified class has template parameters, it needs a <variant> child
element for each template parameter, in order to specify concrete types
for the template instantiation.
The <default_constructor> element is used to specify a default
constructor of a class. It is a child of the <class> element. It has
no attributes or child elements.
The <enum> element specifies an enumeration. It can be a child element
of either the <file> or the <class> elements. The <enum> element
has a name attribute and usually several <enum_value> child
elements. It is used to define enumerations at file or class scope.
The <enum_value> element specifies an enumeration value. It can be a
child element of an <enum> element. The <enum_value> element has
both name and value attributes. The name attribute specifies the
name of an enumeration value, the value attribute specifies its value.
Both attributes are mandatory.
The <event> element is used to specify events that a class can fire.
The <event> element has type and name attributes, and it can have
<parameter> child elements. The <event> element is a child of the
<class> element. The name attribute specifies the event name, and
the type attribute specifies the events return type. For more
information about the type attribute, see the <type> element.
After the usual XML boilerplate
stuff -<?xml version="1.0" encoding="utf-8"?> - each interface
definition file starts with the <file> element. The <file> element
corresponds to a header file in the nGI include directory. The
<file> element does not have any attributes, but it has one or more
<include>, <class>, <static_class> and/or <enum> child elements.
The <include> element can be a child of the <file> element. The
<include> element has a name attribute but no other child elements.
The name attribute is used to build include statements. Include
elements are needed to make classes known to the wrapper generator that
are used as parameters within the file.
The <method> element is used to specify methods. It has name, type
and optional qualifier attributes, and optional <parameter> child
elements. The name attribute specifies the operator name and the
type attribute specifies the return type. For more information about
the type attribute, see the <type> element. If used, the qualifier
attribute can either contain the string const or an empty string. If
the qualifier attribute is missing, the empty string is used by default.
The <parameter>child elements specify the method parameters.
The <parameter> element is used to specify parameters of a method,
property, operator or event. The <parameter> element has name and
type attributes, but no child elements. The <parameter> element can
be a child of the <method>, <static_method>, <unary_operator>,
<binary_operator>, <property> and <event> elements. The name
attribute specifies the parameter name and the type attribute
specifies the parameter type. For more information about the type
attribute, see the <type>element.
The <property> element is used to specify properties. It has name,
type and optional kind attributes, and optional <parameter> child
elements. The name attribute specifies the property name and the
type attribute specifies the property type. For more information about
the type attribute, see the <type> element. The kind attribute can
either contain the strings rw for read/write, ro for read-only. You
can also attach the string ref for reference properties. The
<parameter> child elements specify the property parameters.
The <static_class> element specifies a class with static methods only.
The <static_class> element is a child of the <file> element. The
<static_class> element has a name attribute. The <static_class>
can have <static_method> child elements only.
The <static_method> element is used to specify methods. It has name
and type attributes, and optional <parameter> child elements. The
name attribute specifies the operator name and the type attribute
specifies the return type. For more information about the type
attribute, see the <type>element. The <parameter> child elements
specify the method parameters.
The <type>element is used to specify types for template instantiation.
The <type>element has a name attribute that specifies the type. The
<type>element is a child element of the <variant> element. Type
names are the C++ types, such as int, char or void. Strings are
specified as string. If template parameters need to be used, the angle
brackets have to be replaced by curly braces, because angle brackets
cannot be used within XML files (use buffer{int} instead of
buffer<int>).
The <unary_operator> element is used to specify unary operators. It
has name, type and optional qualifier attributes, but no child
elements. The name attribute specifies the operator name and the
type attribute specifies the return type. For more information about
the type attribute, see the <type> element. If used, the qualifier
attribute can either contain the string const or an empty string. If
the qualifier attribute is missing, the empty string is used by default.
The <variant> element is used to specify concrete types for template
instantiation. It is a child element of the <class> element. The
<variant> element has name and net attributes. The name
attribute specifies the variant name and the net attribute specifies
the mapping to a .NET type. It has one or more <type> child elements
to specify the set of concrete types. For each template parameter of a
nGI class one <variant> element is used.
Native DLL
The native DLL is used to provide some means that the .NET wrapper can
call into. C# can call into a DLL, provided that the functions within
the DLL have a C interface. The first task of the native DLL is
therefore to provide such a DLL which contains C-callable functions. In
order to provide this, the hierarchical class interface had to be
flattened. The other task of the native DLL is to explicitly spell out
the types that the class templates should instantiate. If we have a type
template <typename T> point, and this should be instantiated for types
point<int> and point<double>, the native DLL provides two sets of
functions to do so.
Constructors of a class are mapped onto functions that create an object
using new and return a pointer to the created object. While the object
lives on the heap, member functions of a class take this pointer as
their first parameter, similar to the hidden this pointer of a class
member in C++. The destructor takes this first parameter and calls
delete.

In reality, the opaque type hidden behind the void * pointer is a bit
more complicated for reasons that will become clearer later. The
construct functions return a shared_ptr * that itself points to a pair
of pointers, where the first pointer points to the newed object and the
second pointer points to a string returned by the typeid(...).name()
function.

A handle is a pointer that points to a newed shared_ptr. When the
native DLL deletes the shared_ptr, the shared_ptr deletes the
std::pair * and the first pointer, or - depending on the deallocator
passed when constructing the shared_ptr - deletes the std::pair *
only.
Managed assembly
The managed assembly is written in C#. Most of this assembly is generated but some portions are written by hand. The wrapper generator uses the XML interface description to rebuild the class hierarchy and calls through to the flat native DLL as needed.