<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>SWIG and C#</title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body bgcolor="#FFFFFF">
<H1><a name="CSharp"></a>18 SWIG and C#</H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#csharp_introduction">Introduction</a>
<li><a href="#csharp_differences_java">Differences to the Java module</a>
<li><a href="#CSharp_arrays">C# Arrays</a>
<ul>
<li><a href="#CSharp_arrays_swig_library">The SWIG C arrays library</a>
<li><a href="#CSharp_arrays_pinvoke_default_array_marshalling">Managed arrays using P/Invoke default array marshalling</a>
<li><a href="#CSharp_arrays_pinning">Managed arrays using pinning</a>
</ul>
<li><a href="#csharp_exceptions">C# Exceptions</a>
<ul>
<li><a href="#csharp_exception_example_check_typemap">C# exception example using "check" typemap</a>
<li><a href="#csharp_exception_example_percent_exception">C# exception example using %exception</a>
<li><a href="#csharp_exception_example_exception_specifications">C# exception example using exception specifications</a>
<li><a href="#csharp_custom_application_exception">Custom C# ApplicationException example</a>
</ul>
<li><a href="#csharp_directors">C# Directors</a>
<ul>
<li><a href="#csharp_directors_example">Directors example</a>
<li><a href="#csharp_directors_implementation">Directors implementation</a>
<li><a href="#csharp_director_caveats">Director caveats</a>
</ul>
<li><a href="#csharp_typemap_examples">C# Typemap examples</a>
<ul>
<li><a href="#csharp_memory_management_member_variables">Memory management when returning references to member variables</a>
<li><a href="#csharp_memory_management_objects">Memory management for objects passed to the C++ layer</a>
<li><a href="#csharp_date_marshalling">Date marshalling using the csin typemap and associated attributes</a>
<li><a href="#csharp_date_properties">A date example demonstrating marshalling of C# properties</a>
<li><a href="#csharp_partial_classes">Turning wrapped classes into partial classes</a>
<li><a href="#csharp_extending_proxy_class">Extending proxy classes with additional C# code</a>
</ul>
</ul>
</div>
<!-- INDEX -->



<H2><a name="csharp_introduction"></a>18.1 Introduction</H2>


<p>
The purpose of the C# module is to offer an automated way of accessing existing C/C++ code from .NET languages.
The wrapper code implementation uses C# and the Platform Invoke (PInvoke) interface to access natively compiled C/C++ code.
The PInvoke interface has been chosen over Microsoft's Managed C++ interface as it is portable to both Microsoft Windows and non-Microsoft platforms.
PInvoke is part of the ECMA/ISO C# specification.
It is also better suited for robust production environments due to the Managed C++ flaw called the
<a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/html/vcconMixedDLLLoadingProblem.asp">Mixed DLL Loading Problem</a>.
Swig C# works equally well on non-Microsoft operating systems such as Linux, Solaris and Apple Mac using
<a href="http://www.mono-project.com/">Mono</a> and <a href="http://www.dotgnu.org/pnet.html">Portable.NET</a>.
</p>

<p>
To get the most out of this chapter an understanding of interop is required.
The <a href="http://msdn.microsoft.com">Microsoft Developer Network (MSDN)</a> has a good reference guide in a section titled "Interop Marshaling".
Monodoc, available from the Mono project, has a very useful section titled <a href="http://www.mono-project.com/Interop_with_Native_Libraries">Interop with native libraries</a>.
</p>

<H2><a name="csharp_differences_java"></a>18.2 Differences to the Java module</H2>


<p>
The C# module is very similar to the Java module, so until some more complete documentation has been written,
please use the <a href="Java.html#Java">Java documentation</a> as a guide to using SWIG with C#.
The C# module has the same major SWIG features as the Java module.
The rest of this section should be read in conjunction with the Java documentation as it lists the main differences.

The most notable differences to Java are the following:
<ul>

<li>
When invoking SWIG use the <tt>-csharp</tt> command line option instead of <tt>-java</tt>.
</li>

<li>
The <tt>-nopgcpp</tt> command line option does not exist.
</li>

<li>
The <tt>-package</tt> command line option does not exist.
</li>

<li>
The <tt>-namespace &lt;name&gt;</tt> commandline option will generate all code into the namespace specified by <tt>&lt;name&gt;</tt>.
C# supports nested namespaces that are not lexically nested, so nested namespaces will of course also work. For example:
<tt>-namespace com.bloggs.widget</tt>, will generate code into C# namespaces:

<div class="code"><pre>
namespace com.bloggs.widget {
  ...
}
</pre></div>
Note that by default, the generated C# classes have no namespace and the module name is unrelated to namespaces. The module name is just like in Java and is merely used to name some of the generated classes.
</li>

<li>
The <tt>-dllimport &lt;name&gt;</tt> commandline option specifies the name of the DLL for the <tt>DllImport</tt> attribute for every PInvoke method. If this commandline option is not given, the <tt>DllImport</tt> DLL name is the same as the module name. This option is useful for when one wants to invoke SWIG multiple times on different modules, yet compile all the resulting code into a single DLL.
</li>

<li>
C/C++ variables are wrapped with C# properties and not JavaBean style getters and setters.
</li>

<li>
Global constants are generated into the module class. There is no constants interface.
</li>

<li>
There is no implementation for type unsafe enums - not deemed necessary.
</li>

<li>
The default enum wrapping approach is proper C# enums, not typesafe enums.
<br>
Note that %csconst(0) will be ignored when wrapping C/C++ enums with proper C# enums.
This is because C# enum items must be initialised from a compile time constant.
If an enum item has an initialiser and the initialiser doesn't compile as C# code,
then the %csconstvalue directive must be used as %csconst(0) will have no effect.
If it was used, it would generate an illegal runtime initialisation via a PInvoke call.
</li>

<li>
C# doesn't support the notion of throws clauses.
Therefore there is no 'throws' typemap attribute support for adding exception classes to a throws clause.
Likewise there is no need for an equivalent to <tt>%javaexception</tt>.
In fact, throwing C# exceptions works quite differently, see <a href="CSharp.html#csharp_exceptions">C# Exceptions</a> below.
</li>

<li>
The majority of the typemaps are in csharp.swg, not java.swg.
</li>

<li>
<p>Typemap equivalent names:</p>

<div class="code"><pre>
jni                         -&gt; ctype
jtype                       -&gt; imtype
jstype                      -&gt; cstype
javain                      -&gt; csin
javaout                     -&gt; csout
javadirectorin              -&gt; csdirectorin
javadirectorout             -&gt; csdirectorout
javainterfaces              -&gt; csinterfaces and csinterfaces_derived
javabase                    -&gt; csbase
javaclassmodifiers          -&gt; csclassmodifiers
javacode                    -&gt; cscode
javaimports                 -&gt; csimports
javabody                    -&gt; csbody
javafinalize                -&gt; csfinalize
javadestruct                -&gt; csdestruct
javadestruct_derived        -&gt; csdestruct_derived
</pre></div>

</li>

<li>
<p>Additional typemaps:</p>

<div class="code"><pre>
csvarin                     C# code property set typemap
csvarout                    C# code property get typemap
csattributes                C# attributes for attaching to proxy classes/enums
</pre></div>

</li>

<li>
<p>Feature equivalent names:</p>
<div class="code"><pre>
%javaconst                  -&gt; %csconst
%javaconstvalue             -&gt; %csconstvalue
%javamethodmodifiers        -&gt; %csmethodmodifiers
</pre></div>
</li>

<li>
<p>Pragma equivalent names:</p>
<div class="code"><pre>
%pragma(java)               -&gt; %pragma(csharp)
jniclassbase                -&gt; imclassbase
jniclassclassmodifiers      -&gt; imclassclassmodifiers
jniclasscode                -&gt; imclasscode
jniclassimports             -&gt; imclassimports
jniclassinterfaces          -&gt; imclassinterfaces
</pre></div>
</li>

<li>
<p>Special variable equivalent names:</p>
<div class="code"><pre>
$javaclassname              -&gt; $csclassname
$&amp;javaclassname             -&gt; $&amp;csclassname
$*javaclassname             -&gt; $*csclassname
$javainput                  -&gt; $csinput
$jnicall                    -&gt; $imcall
</pre></div>
</li>

<li>
<p>
Unlike the "javain" typemap, the "csin" typemap does not support the 'pgcpp' attribute as the C# module does not have a premature garbage collection prevention parameter. 
The "csin" typemap supports additional optional attributes called 'cshin' and 'terminator'. 
The 'cshin' attribute should contain the parameter type and name whenever a <a href="Java.html#java_constructor_helper_function">constructor helper function</a> is generated due to the 'pre' or 'post' attributes. 
The 'terminator' attribute normally just contains a closing brace for when the 'pre' attribute contains an opening brace, such as when a C# <tt>using</tt> or <tt>fixed</tt> block is started.
Note that 'pre', 'post', 'terminator' and 'cshin' attributes are not used for marshalling the property set.
Please see the <a href="#csharp_date_marshalling">Date marshalling example</a> and <a href="#csharp_date_properties">Date marshalling of properties example</a> for further understanding of these "csin" applicable attributes.
</p>
</li>

<li>
<p>
Support for asymmetric type marshalling. The 'ctype', 'imtype' and 'cstype' typemaps support an optional <tt>out</tt> attribute which is used for output types.
If this typemap attribute is specified, then the type specified in the attribute is used for output types and
the type specified in the typemap itself is used for the input type.
If this typemap attribute is not specified, then the type used for both input and output is the type specified in the typemap.
An example shows that <tt>char *</tt> could be marshalled in different ways, 
</p>

<div class="code">
<pre>
%typemap(imtype, out="IntPtr") char * "string"
char * function(char *);
</pre>
</div>

<p>
The output type is thus IntPtr and the input type is string. The resulting intermediary C# code is:
</p>

<div class="code">
<pre>
public static extern IntPtr function(string jarg1);
</pre>
</div>

</li>

<li>
<p>
Support for type attributes.
The 'imtype' and 'cstype' typemaps can have an optional <tt>inattributes</tt> and <tt>outattributes</tt> typemap attribute.
There are C# attributes and typemap attributes, don't get confused!!
The C# attributes specified in these typemap attributes are generated wherever the type is used in the C# wrappers.
These can be used to specify any C# attribute associated with a C/C++ type, but are more typically used for the C# <tt>MarshalAs</tt> attribute.
For example:
</p>

<div class="code">
<pre>
%typemap(imtype,
         inattributes="[MarshalAs(UnmanagedType.LPStr)]",
         outattributes="[return: MarshalAs(UnmanagedType.LPStr)]") const char * "String"

const char * GetMsg() {}
void SetMsg(const char *msg) {}
</pre>
</div>

<p>
The intermediary class will then have the marshalling as specified by everything in the 'imtype' typemap:
</p>

<div class="code">
<pre>
class examplePINVOKE {
  ...
  [DllImport("example", EntryPoint="CSharp_GetMsg")]
  [return: MarshalAs(UnmanagedType.LPStr)]
  public static extern String GetMsg();

  [DllImport("example", EntryPoint="CSharp_SetMsg")]
  public static extern void SetMsg([MarshalAs(UnmanagedType.LPStr)]String jarg1);
}
</pre>
</div>

<p>
Note that the <tt>DllImport</tt> attribute is always generated, irrespective of any additional attributes specified.
</p>

<p>
These attributes are associated with the C/C++ parameter type or return type, which is subtly different to 
the attribute features and typemaps covered next.
Note that all these different C# attributes can be combined so that a method has more than one attribute.
</p>
</li>

<li>
<p>
Support for attaching C# attributes to wrapped methods and variables.
This is done using the <tt>%csattributes</tt> feature, see <a href="Customization.html#features">%feature directives</a>.
Note that C# attributes are attached to proxy classes and enums using the <tt>csattributes</tt> typemap.
For example, imagine we have a custom attribute class, <tt>ThreadSafeAttribute</tt>, for labelling thread safety.
The following SWIG code shows how to attach this C# attribute to some methods and the class declaration itself:
</p>

<div class="code">
<pre>
%typemap(csattributes) AClass          "[ThreadSafe]"
%csattributes AClass::AClass(double d) "[ThreadSafe(false)]"
%csattributes AClass::AMethod()        "[ThreadSafe(true)]"

%inline %{
class AClass {
public:
  AClass(double a) {}
  void AMethod() {}
};
%}
</pre>
</div>

<p>
will generate a C# proxy class:
</p>

<div class="code">
<pre>
[ThreadSafe]
public class AClass : IDisposable {
  ...
  [ThreadSafe(false)]
  public AClass(double a) ...

  [ThreadSafe(true)]
  public void AMethod() ...
}
</pre>
</div>

<p>
If C# attributes need adding to the <tt>set</tt> or <tt>get</tt> part of C# properties, when wrapping C/C++ variables,
they can be added using the 'csvarin' and 'csvarout' typemaps respectively.
Note that the type used for the property is specified in the 'cstype' typemap.
If the 'out' attribute exists in this typemap, then the type used is from the 'out' attribute.
</p>
</li>

<li>
<p>
The intermediary classname has <tt>PINVOKE</tt> appended after the module name instead of <tt>JNI</tt>, for example <tt>modulenamePINVOKE</tt>.
</p>
</li>

<li>
<p>
The <tt>%csmethodmodifiers</tt> feature can also be applied to variables as well as methods.
In addition to the default <tt>public</tt> modifier that SWIG generates when <tt>%csmethodmodifiers</tt> is not
specified, the feature will also replace the <tt>virtual</tt>/<tt>new</tt>/<tt>override</tt> modifiers that SWIG thinks is appropriate.
This feature is useful for some obscure cases where SWIG might get the <tt>virtual</tt>/<tt>new</tt>/<tt>override</tt> modifiers incorrect, for example with multiple inheritance.
</p>
</li>

<li>
<a name="csharp_module_directive"></a>
<p>
The name of the intermediary class can be changed from its default, that is, the module name with PINVOKE appended after it. 
The module directive attribute <tt>imclassname</tt> is used to achieve this:
</p>

<div class="code">
<pre>
%module (imclassname="name") modulename
</pre>
</div>

<p>
If <tt>name</tt> is the same as <tt>modulename</tt> then the module class name gets changed
from <tt>modulename</tt> to <tt>modulenameModule</tt>.
</p>
</li>

<li>
There is no additional 'premature garbage collection prevention parameter' as the marshalling of the <tt>HandleRef</tt> object
takes care of ensuring a reference to the proxy class is held until the unmanaged call completed.
</li>

</ul>

<p>
<b><tt>$dllimport</tt></b><br>
This is a C# only special variable that can be used in typemaps, pragmas, features etc.
The special variable will get translated into the value specified by the <tt>-dllimport</tt> commandline option
if specified, otherwise it is equivalent to the <b>$module</b> special variable.
</p>

<p>
<b><tt>$imclassname</tt></b><br>
This special variable expands to the intermediary class name. For C# this is usually the same as '$modulePINVOKE' ('$moduleJNI' for Java),
unless the imclassname attribute is specified in the <a href="CSharp.html#csharp_module_directive">%module directive</a>.
</p>

<p>
The directory <tt>Examples/csharp</tt> has a number of simple examples. 
Visual Studio .NET 2003 solution and project files are available for compiling with the Microsoft .NET C# compiler on Windows.
If your SWIG installation went well on a Unix environment and your C# compiler was detected, you should be able to type <tt>make</tt> in each example directory, 
then <tt>ilrun runme.exe</tt> (Portable.NET C# compiler) or <tt>mono runme.exe</tt> (Mono C# compiler) to run the examples.
Windows users can also get the examples working using a
<a href="http://www.cygwin.com">Cygwin</a> or <a href="http://www.mingw.org">MinGW</a> environment for automatic configuration of the example makefiles.
Any one of the three C# compilers (Portable.NET, Mono or Microsoft) can be detected from within a Cygwin or Mingw environment if installed in your path. 

<H2><a name="CSharp_arrays"></a>18.3 C# Arrays</H2>


<p>
There are various ways to pass arrays from C# to C/C++. 
The default wrapping treats arrays as pointers and as such simple type wrapper classes are generated, 
eg <tt>SWIGTYPE_p_int</tt> when wrapping the C type <tt>int []</tt> or <tt>int *</tt>.
This gives a rather restricted use of the underlying unmanaged code and the most practical way to use arrays is to enhance or customise
with one of the following three approaches; namely the SWIG C arrays library, P/Invoke default array marshalling or 
pinned arrays.
</p>

<H3><a name="CSharp_arrays_swig_library"></a>18.3.1 The SWIG C arrays library</H3>


<p>
The C arrays library keeps all the array memory in the unmanaged layer.
The library is available to all language modules and is documented in the <a href="Library.html#Library_carrays">carrays.i library</a> section.
Please refer to this section for details, but for convenience, the C# usage for the two examples outlined there is shown below.
</p>

<p>
For the <tt>%array_functions</tt> example, the equivalent usage would be:
</p>

<div class="code">
<pre>
SWIGTYPE_p_double a = example.new_doubleArray(10);  // Create an array
for (int i=0; i&lt;10; i++)
  example.doubleArray_setitem(a,i,2*i);             // Set a value
example.print_array(a);                             // Pass to C
example.delete_doubleArray(a);                      // Destroy array
</pre>
</div>

<p>
and for the <tt>%array_class</tt> example, the equivalent usage would be:
</p>

<div class="code">
<pre>
doubleArray c = new doubleArray(10);    // Create double[10]
for (int i=0; i&lt;10; i++)
  c.setitem(i, 2*i);                    // Assign values
example.print_array(c.cast());          // Pass to C
</pre>
</div>


<H3><a name="CSharp_arrays_pinvoke_default_array_marshalling"></a>18.3.2 Managed arrays using P/Invoke default array marshalling</H3>


<p>
In the P/Invoke default marshalling scheme, one needs to designate whether the invoked function will treat a managed
array parameter as input, output, or both. When the function is invoked, the CLR allocates a separate chunk of memory as big as the given managed array, 
which is automatically released at the end of the function call. If the array parameter is marked as being input, the content of the managed array is copied
into this buffer when the call is made. Correspondingly, if the array parameter is marked as being output, the contents of the reserved buffer are copied
back into the managed array after the call returns. A pointer to to this buffer
is passed to the native function.
</p>

<p>
The reason for allocating a separate buffer is to leave the CLR free to relocate the managed array object 
during garbage collection. If the overhead caused by the copying is causing a significant performance penalty, consider pinning the managed array and
passing a direct reference as described in the next section.
</p>

<p>
For more information on the subject, see  the
<a href="http://msdn.microsoft.com/en-us/library/z6cfh6e6(VS.80).aspx">Default Marshaling for Arrays</a> article
on MSDN.
</p>


<p>
The P/Invoke default marshalling is supported by the <tt>arrays_csharp.i</tt> library via the INPUT, OUTPUT and INOUT typemaps. 
Let's look at some example usage. Consider the following C function:
</p>
<div class="code">
<pre>
void myArrayCopy(int *sourceArray, int *targetArray, int nitems);
</pre>
</div>

<p>
We can now instruct SWIG to use the default marshalling typemaps by 
</p>

<div class="code">
<pre>
%include "arrays_csharp.i"

%apply int INPUT[]  {int *sourceArray}
%apply int OUTPUT[] {int *targetArray}
</pre>
</div>

<p>
As a result, we get the following method in the module class:
</p>

<div class="code">
<pre>
public static void myArrayCopy(int[] sourceArray, int[] targetArray, int nitems) {
    examplePINVOKE.myArrayCopy(sourceArray, targetArray, nitems);
}
</pre>
</div>

<p>
If we look beneath the surface at the corresponding intermediary class code, we see
that SWIG has generated code that uses attributes 
(from the System.Runtime.InteropServices namespace) to tell the CLR to use default
marshalling for the arrays:
</p>

<div class="code">
<pre>
[DllImport("example", EntryPoint="CSharp_myArrayCopy")]
public static extern void myArrayCopy([In, MarshalAs(UnmanagedType.LPArray)]int[] jarg1, 
                                      [Out, MarshalAs(UnmanagedType.LPArray)]int[] jarg2, int jarg3);
</pre>
</div>

<p>
As an example of passing an inout array (i.e. the target function will both read from and
write to the array), consider this C function that swaps a given number of elements
in the given arrays:
</p>

<div class="code">
<pre>
void myArraySwap(int *array1, int *array2, int nitems);
</pre>
</div>

<p>
Now, we can instruct SWIG to wrap this by
</p>

<div class="code">
<pre>
%include "arrays_csharp.i"

%apply int INOUT[] {int *array1}
%apply int INOUT[] {int *array2}
</pre>
</div>

<p>
This results in the module class method
</p>

<div class="code">
<pre>
  public static void myArraySwap(int[] array1, int[] array2, int nitems) {
    examplePINVOKE.myArraySwap(array1, array2, nitems);
  }
</pre>
</div>

<p>
and intermediate class method
</p>

<div class="code">
<pre>
  [DllImport("example", EntryPoint="CSharp_myArraySwap")]
  public static extern void myArraySwap([In, Out, MarshalAs(UnmanagedType.LPArray)]int[] jarg1, 
                                        [In, Out, MarshalAs(UnmanagedType.LPArray)]int[] jarg2, int jarg3);
</pre>
</div>


<H3><a name="CSharp_arrays_pinning"></a>18.3.3 Managed arrays using pinning</H3>


<p>
It is also possible to pin a given array in memory (i.e. fix its location in memory), obtain a
direct pointer to it, and then pass this pointer to the wrapped C/C++ function. This approach
involves no copying, but it makes the work of the garbage collector harder as 
the managed array object can not be relocated before the fix on the array is released. You should avoid 
fixing arrays in memory in cases where the control may re-enter the managed side via a callback and/or
another thread may produce enough garbage to trigger garbage collection.
</p>

<p>
For more information, see the <a href="http://msdn.microsoft.com/en-us/library/f58wzh21(VS.80).aspx">fixed statement</a> in the C# language reference.
</p>


<p>
Now let's look at an example using pinning, thus avoiding the CLR making copies
of the arrays passed as parameters. The <tt>arrays_csharp.i</tt> library file again provides the required support via the <tt>FIXED</tt> typemaps.
Let's use the same function from the previous section:
</p>

<div class="code">
<pre>
void myArrayCopy(int *sourceArray, int *targetArray, int nitems);
</pre>
</div>

<p>
We now need to declare the module class method unsafe, as we are using pointers:
</p>

<div class="code">
<pre>
%csmethodmodifiers myArrayCopy "public unsafe";
 </pre>
</div>

<p>
Apply the appropriate typemaps to the array parameters:
</p>

<div class="code">
<pre>
%include "arrays_csharp.i"

%apply int FIXED[] {int *sourceArray}
%apply int FIXED[] {int *targetArray}
</pre>
</div>

<p>
Notice that there is no need for separate in, out or inout typemaps as is the
case when using P/Invoke default marshalling. 
</p>

<p>
As a result, we get the following method in the module class:
</p>

<div class="code">
<pre>
  public unsafe static void myArrayCopy(int[] sourceArray, int[] targetArray, int nitems) {
    fixed ( int *swig_ptrTo_sourceArray = sourceArray ) {
    fixed ( int *swig_ptrTo_targetArray = targetArray ) {
    {
      examplePINVOKE.myArrayCopy((IntPtr)swig_ptrTo_sourceArray, (IntPtr)swig_ptrTo_targetArray, nitems);
    }
    }
    }
  }
</pre>
</div>

<p>
On the method signature level the only difference to the version using P/Invoke default
marshalling is the "unsafe" quantifier, which is required because we are handling pointers.
</p>

<p>
Also the intermediate class method looks a little different from the default marshalling
example - the method is expecting an IntPtr as the parameter type.
</p>

<div class="code">
<pre>
[DllImport("example", EntryPoint="CSharp_myArrayCopy")]
public static extern void myArrayCopy(IntPtr jarg1, IntPtr jarg2, int jarg3);
</pre>
</div>



<H2><a name="csharp_exceptions"></a>18.4 C# Exceptions</H2>


<p>
It is possible to throw a C# Exception from C/C++ code.
SWIG already provides the framework for throwing C# exceptions if it is able to detect that a C++ exception could be thrown.
Automatically detecting that a C++ exception could be thrown is only possible when a C++ exception specification is used,
see <a href="SWIGPlus.html#SWIGPlus_exception_specifications">Exception specifications</a>. 
The <a href="Customization.html#exception">Exception handling with %exception</a> section details the <tt>%exception</tt> feature.
Customised code for handling exceptions with or without a C++ exception specification is possible and the details follow.
However anyone wishing to do this should be familiar with the contents of the sections referred to above.
</p>

<p>
Unfortunately a C# exception cannot simply be thrown from unmanaged code for a variety of reasons.
Most notably being that throwing a C# exception results in exceptions being thrown across the C PInvoke interface and C does not understand exceptions.
The design revolves around a C# exception being constructed and stored as a pending exception, to be thrown only when the unmanaged code has completed.
Implementing this is a tad involved and there are thus some unusual typemap constructs.
Some practical examples follow and they should be read in conjunction with the rest of this section.
</p>

<p>
First some details about the design that must be followed.
Each typemap or feature that generates <b>unmanaged code</b> supports an attribute called <tt>canthrow</tt>.
This is simply a flag which when set indicates that the code in the typemap/feature has code which might want to throw a C# exception.
The code in the typemap/feature can then raise a C# exception by calling one of the C functions,
<tt>SWIG_CSharpSetPendingException()</tt> or <tt>SWIG_CSharpSetPendingExceptionArgument()</tt>.
When called, the function makes a callback into the managed world via a delegate.
The callback creates and stores an exception ready for throwing when the unmanaged code has finished.
The typemap/feature unmanaged code is then expected to force an immediate return from the unmanaged wrapper function,
so that the pending managed exception can then be thrown.
The support code has been carefully designed to be efficient as well as thread-safe.
However to achieve the goal of efficiency requires some optional code generation in the <b>managed code</b> typemaps.
Code to check for pending exceptions is generated if and only if the unmanaged code has code to set a pending exception,
that is if the <tt>canthrow</tt> attribute is set.
The optional managed code is generated using the <tt>excode</tt> typemap attribute and <tt>$excode</tt> special variable in the relevant managed code typemaps.
Simply, if any relevant unmanaged code has the <tt>canthrow</tt> attribute set, then any occurrences of <tt>$excode</tt>
is replaced with the code in the <tt>excode</tt> attribute.
If the <tt>canthrow</tt> attribute is not set, then any occurrences of <tt>$excode</tt> are replaced with nothing.
</p>

<p>
The prototypes for the <tt>SWIG_CSharpSetPendingException()</tt> and <tt>SWIG_CSharpSetPendingExceptionArgument()</tt> functions are
</p>

<div class="code">
<pre>
static void SWIG_CSharpSetPendingException(SWIG_CSharpExceptionCodes code,
                                           const char *msg);

static void SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpExceptionArgumentCodes code,
                                                   const char *msg,
                                                   const char *param_name);
</pre>
</div>

<p>
The first parameter defines which .NET exceptions can be thrown:
</p>

<div class="code">
<pre>
typedef enum {
  SWIG_CSharpApplicationException,
  SWIG_CSharpArithmeticException,
  SWIG_CSharpDivideByZeroException,
  SWIG_CSharpIndexOutOfRangeException,
  SWIG_CSharpInvalidCastException,
  SWIG_CSharpInvalidOperationException,
  SWIG_CSharpIOException,
  SWIG_CSharpNullReferenceException,
  SWIG_CSharpOutOfMemoryException,
  SWIG_CSharpOverflowException,
  SWIG_CSharpSystemException
} SWIG_CSharpExceptionCodes;

typedef enum {
  SWIG_CSharpArgumentException,
  SWIG_CSharpArgumentNullException,
  SWIG_CSharpArgumentOutOfRangeException,
} SWIG_CSharpExceptionArgumentCodes;
</pre>
</div>

<p>
where, for example, <tt>SWIG_CSharpApplicationException</tt> corresponds to the .NET exception, <tt>ApplicationException</tt>.
The <tt>msg</tt> and <tt>param_name</tt> parameters contain the C# exception message and parameter name associated with the exception.
</p>


<p>
The <tt>%exception</tt> feature in C# has the <tt>canthrow</tt> attribute set.
The <tt>%csnothrowexception</tt> feature is like <tt>%exception</tt>, but it does not have the <tt>canthrow</tt> attribute
set so should only be used when a C# exception is not created.
</p>


<H3><a name="csharp_exception_example_check_typemap"></a>18.4.1 C# exception example using "check" typemap</H3>


<p>
Lets say we have the following simple C++ method:
</p>


<div class="code">
<pre>
void positivesonly(int number);
</pre>
</div>

<p>
and we want to check that the input <tt>number</tt> is always positive and if not throw a C# <tt>ArgumentOutOfRangeException</tt>.
The "check" typemap is designed for checking input parameters. Below you will see the <tt>canthrow</tt> attribute is set because
the code contains a call to <tt>SWIG_CSharpSetPendingExceptionArgument()</tt>. The full example follows:
</p>

<div class="code">
<pre>
%module example

%typemap(check, canthrow=1) int number %{
if ($1 &lt; 0) {
  SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentOutOfRangeException,
                                         "only positive numbers accepted", "number");
  return $null;
}
// SWIGEXCODE is a macro used by many other csout typemaps
%define SWIGEXCODE
 "\n    if ($modulePINVOKE.SWIGPendingException.Pending)"
 "\n      throw $modulePINVOKE.SWIGPendingException.Retrieve();"
%enddef
%typemap(csout, excode=SWIGEXCODE) void {
    $imcall;$excode
  }
%}

%inline %{

void positivesonly(int number) {
}

%}
</pre>
</div>

<p>
When the following C# code is executed:
</p>

<div class="code">
<pre>
public class runme {
    static void Main() {
      example.positivesonly(-1);
    }
}
</pre>
</div>

<p>
The exception is thrown:
</p>

<div class="code">
<pre>
Unhandled Exception: System.ArgumentOutOfRangeException: only positive numbers accepted
Parameter name: number
in &lt;0x00034&gt; example:positivesonly (int)
in &lt;0x0000c&gt; runme:Main ()
</pre>
</div>

<p>
Now let's analyse the generated code to gain a fuller understanding of the typemaps. The generated unmanaged C++ code is:
</p>


<div class="code">
<pre>
SWIGEXPORT void SWIGSTDCALL CSharp_positivesonly(int jarg1) {
    int arg1 ;
    
    arg1 = (int)jarg1; 
    
    if (arg1 &lt; 0) {
        SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentOutOfRangeException,
                                               "only positive numbers accepted", "number");
        return ;
    }
    
    positivesonly(arg1);
    
}
</pre>
</div>

<p>
This largely comes from the "check" typemap. The managed code in the module class is:
</p>

<div class="code">
<pre>
public class example {
  public static void positivesonly(int number) {
    examplePINVOKE.positivesonly(number);
    if (examplePINVOKE.SWIGPendingException.Pending)
      throw examplePINVOKE.SWIGPendingException.Retrieve();
  }

}
</pre>
</div>

<p>
This comes largely from the "csout" typemap. 
</p>

<p>
The "csout" typemap is the same as the default void "csout" typemap so is not strictly necessary for the example.
However, it is shown to demonstrate what managed output code typemaps should contain,
that is, a <tt>$excode</tt> special variable and an <tt>excode</tt> attribute.
Also note that <tt>$excode</tt> is expanded into the code held in the <tt>excode</tt> attribute.
The <tt>$imcall</tt> as always expands into <tt>examplePINVOKE.positivesonly(number)</tt>.
The exception support code in the intermediary class, <tt>examplePINVOKE</tt>, is not shown, but is contained within the inner classes,
<tt>SWIGPendingException</tt> and <tt>SWIGExceptionHelper</tt> and is always generated.
These classes can be seen in any of the generated wrappers.
However, all that is required of a user is as demonstrated in the "csin" typemap above.
That is, is to check <tt>SWIGPendingException.Pending</tt> and to throw the exception returned by <tt>SWIGPendingException.Retrieve()</tt>.
</p>

<p>
If the "check" typemap did not exist, then
the following module class would instead be generated:
</p>

<div class="code">
<pre>
public class example {
  public static void positivesonly(int number) {
    examplePINVOKE.positivesonly(number);
  }

}
</pre>
</div>

<p>
Here we see the pending exception checking code is omitted.
In fact, the code above would be generated if the <tt>canthrow</tt> attribute was not in the "check" typemap, such as:
</p>

<div class="code">
<pre>
%typemap(check) int number %{
if ($1 &lt; 0) {
  SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentOutOfRangeException,
                                         "only positive numbers accepted", "number");
  return $null;
}
%}
</pre>
</div>

<p>
Note that if SWIG detects you have used <tt>SWIG_CSharpSetPendingException()</tt> or <tt>SWIG_CSharpSetPendingExceptionArgument()</tt>
without setting the <tt>canthrow</tt> attribute you will get a warning message similar to
</p>

<div class="code">
<pre>
example.i:21: Warning(845): Unmanaged code contains a call to a SWIG_CSharpSetPendingException
method and C# code does not handle pending exceptions via the canthrow attribute.
</pre>
</div>
<p>
Actually it will issue this warning for any function beginning with <tt>SWIG_CSharpSetPendingException</tt>.
</P>

<H3><a name="csharp_exception_example_percent_exception"></a>18.4.2 C# exception example using %exception</H3>


<p>
Let's consider a similar, but more common example that throws a C++ exception from within a wrapped function.
We can use <tt>%exception</tt> as mentioned in <a href="Customization.html#exception">Exception handling with %exception</a>.
</p>

<div class="code">
<pre>
%exception negativesonly(int value) %{
try {
  $action
} catch (std::out_of_range e) {
  SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, e.what());
}
%}

%inline %{
#include &lt;stdexcept&gt;
void negativesonly(int value) {
  if (value &gt;= 0)
    throw std::out_of_range("number should be negative");
}
%}
</pre>
</div>

<p>
The generated unmanaged code this time catches the C++ exception and converts it into a C# <tt>ApplicationException</tt>.
</p>

<div class="code">
<pre>
SWIGEXPORT void SWIGSTDCALL CSharp_negativesonly(int jarg1) {
    int arg1 ;
    
    arg1 = (int)jarg1; 
    
    try {
        negativesonly(arg1);
        
    } catch (std::out_of_range e) {
        SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, e.what());
        return ;
    }
    
}
</pre>
</div>

<p>
The managed code generated does check for the pending exception as mentioned earlier as the C# version of <tt>%exception</tt> has the <tt>canthrow</tt> attribute set by default:
</p>

<div class="code">
<pre>
  public static void negativesonly(int value) {
    examplePINVOKE.negativesonly(value);
    if (examplePINVOKE.SWIGPendingException.Pending)
      throw examplePINVOKE.SWIGPendingException.Retrieve();
  }
</pre>
</div>

<H3><a name="csharp_exception_example_exception_specifications"></a>18.4.3 C# exception example using exception specifications</H3>


<p>
When C++ exception specifications are used, SWIG is able to detect that the method might throw an exception.
By default SWIG will automatically generate code to catch the exception and convert it into a managed <tt>ApplicationException</tt>,
as defined by the default "throws" typemaps.
The following example has a user supplied "throws" typemap which is used whenever an exception specification contains a <tt>std::out_of_range</tt>,
such as the <tt>evensonly</tt> method below.
</p>

<div class="code">
<pre>
%typemap(throws, canthrow=1) std::out_of_range {
  SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentException, $1.what(), NULL);
  return $null;
}

%inline %{
#include &lt;stdexcept&gt;
void evensonly(int input) throw (std::out_of_range) {
  if (input%2 != 0)
    throw std::out_of_range("number is not even");
}
%}
</pre>
</div>

<p>
Note that the type for the throws typemap is the type in the exception specification.
SWIG generates a try catch block with the throws typemap code in the catch handler.
</p>

<div class="code">
<pre>
SWIGEXPORT void SWIGSTDCALL CSharp_evensonly(int jarg1) {
    int arg1 ;
    
    arg1 = (int)jarg1; 
    try {
        evensonly(arg1);
    }
    catch(std::out_of_range &amp;_e) {
      {
          SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentException, (&amp;_e)-&gt;what(), NULL);
          return ;
      }
    }
    
}
</pre>
</div>

<p>
Multiple catch handlers are generated should there be more than one exception specifications declared.
</p>

<H3><a name="csharp_custom_application_exception"></a>18.4.4 Custom C# ApplicationException example</H3>


<p>
This example involves a user defined exception.
The conventional .NET exception handling approach is to create a custom <tt>ApplicationException</tt> and throw it in your application.
The goal in this example is to convert the STL <tt>std::out_of_range</tt> exception into one of these custom .NET exceptions.
</p>


<p>
The default exception handling is quite easy to use as the <tt>SWIG_CSharpSetPendingException()</tt> and <tt>SWIG_CSharpSetPendingExceptionArgument()</tt>
methods are provided by SWIG.
However, for a custom C# exception, the boiler plate code that supports these functions needs replicating.
In essence this consists of some C/C++ code and C# code.
The C/C++ code can be generated into the wrapper file using the <tt>%insert(runtime)</tt> directive and
the C# code can be generated into the intermediary class using the <tt>imclasscode</tt> pragma as follows:

</p>

<div class="code">
<pre>
%insert(runtime) %{
  // Code to handle throwing of C# CustomApplicationException from C/C++ code.
  // The equivalent delegate to the callback, CSharpExceptionCallback_t, is CustomExceptionDelegate
  // and the equivalent customExceptionCallback instance is customDelegate
  typedef void (SWIGSTDCALL* CSharpExceptionCallback_t)(const char *);
  CSharpExceptionCallback_t customExceptionCallback = NULL;

  extern "C" SWIGEXPORT
  void SWIGSTDCALL CustomExceptionRegisterCallback(CSharpExceptionCallback_t customCallback) {
    customExceptionCallback = customCallback;
  }

  // Note that SWIG detects any method calls named starting with
  // SWIG_CSharpSetPendingException for warning 845
  static void SWIG_CSharpSetPendingExceptionCustom(const char *msg) {
    customExceptionCallback(msg);
  }
%}

%pragma(csharp) imclasscode=%{
  class CustomExceptionHelper {
    // C# delegate for the C/C++ customExceptionCallback
    public delegate void CustomExceptionDelegate(string message);
    static CustomExceptionDelegate customDelegate =
                                   new CustomExceptionDelegate(SetPendingCustomException);

    [DllImport("$dllimport", EntryPoint="CustomExceptionRegisterCallback")]
    public static extern
           void CustomExceptionRegisterCallback(CustomExceptionDelegate customCallback);

    static void SetPendingCustomException(string message) {
      SWIGPendingException.Set(new CustomApplicationException(message));
    }

    static CustomExceptionHelper() {
      CustomExceptionRegisterCallback(customDelegate);
    }
  }
  static CustomExceptionHelper exceptionHelper = new CustomExceptionHelper();
%}
</pre>
</div>

<p>
The method stored in the C# delegate instance, <tt>customDelegate</tt> is what gets called by the C/C++ callback.
However, the equivalent to the C# delegate, that is the C/C++ callback, needs to be assigned before any unmanaged code is executed.
This is achieved by putting the initialisation code in the intermediary class.
Recall that the intermediary class contains all the PInvoke methods, so the static variables in the intermediary class will be initialised
before any of the PInvoke methods in this class are called.
The <tt>exceptionHelper</tt> static variable ensures the C/C++ callback is initialised with the value in <tt>customDelegate</tt> by calling
the <tt>CustomExceptionRegisterCallback</tt> method in the <tt>CustomExceptionHelper</tt> static constructor.
Once this has been done, unmanaged code can make callbacks into the managed world as <tt>customExceptionCallback</tt> will be initialised with a valid callback/delegate.
Any calls to <tt>SWIG_CSharpSetPendingExceptionCustom()</tt> will make the callback to create the pending exception in the same way that
<tt>SWIG_CSharpSetPendingException()</tt> and <tt>SWIG_CSharpSetPendingExceptionArgument()</tt> does.
In fact the method has been similarly named so that SWIG can issue the warning about missing <tt>canthrow</tt> attributes as discussed earlier.
It is an invaluable warning as it is easy to forget the <tt>canthrow</tt> attribute when writing typemaps/features.
</p>

<p>
The <tt>SWIGPendingException</tt> helper class is not shown, but is generated as an inner class into the intermediary class.
It stores the pending exception in Thread Local Storage so that the exception handling mechanism is thread safe.
</p>

<p>
The boiler plate code above must be used in addition to a handcrafted <tt>CustomApplicationException</tt>:
</p>

<div class="code">
<pre>
// Custom C# Exception
class CustomApplicationException : System.ApplicationException {
  public CustomApplicationException(string message) 
    : base(message) {
  }
}
</pre>
</div>

<p>
and the SWIG interface code:
</p>

<div class="code">
<pre>
%typemap(throws, canthrow=1) std::out_of_range {
  SWIG_CSharpSetPendingExceptionCustom($1.what());
  return $null;
}

%inline %{
void oddsonly(int input) throw (std::out_of_range) {
  if (input%2 != 1)
    throw std::out_of_range("number is not odd");
}
%}
</pre>
</div>

<p>
The "throws" typemap now simply calls our new <tt>SWIG_CSharpSetPendingExceptionCustom()</tt> function so that the exception can be caught, as such:
</p>

<div class="code">
<pre>
try {
  example.oddsonly(2);
} catch (CustomApplicationException e) {
  ...
}
</pre>
</div>

<H2><a name="csharp_directors"></a>18.5 C# Directors</H2>


<p>
The SWIG directors feature adds extra code to the generated C# proxy classes that enable these classes to be used in cross-language polymorphism.
Essentially, it enables unmanaged C++ code to call back into managed code for virtual methods so that a C# class can derive from a wrapped C++ class.
</p>

<p>
The following sections provide information on the C# director implementation and contain most of the information required to use the C# directors.
However, the <a href="Java.html#java_directors">Java directors</a> section should also be read in order to gain more insight into directors.
</p>

<H3><a name="csharp_directors_example"></a>18.5.1 Directors example</H3>


<p>
Imagine we are wrapping a C++ base class, <tt>Base</tt>, from which we would like to inherit in C#.
Such a class is shown below as well as another class, <tt>Caller</tt>, which calls the virtual method <tt>UIntMethod</tt>
from pure unmanaged C++ code.
</p>


<div class="code">
<pre>
// file: example.h
class Base {
public:
  virtual ~Base() {}

  virtual unsigned int UIntMethod(unsigned int x) {
    std::cout &lt;&lt; "Base - UIntMethod(" &lt;&lt; x &lt;&lt; ")" &lt;&lt; std::endl;
    return x;
  }
  virtual void BaseBoolMethod(const Base &amp;b, bool flag) {}
};

class Caller {
public:
  Caller(): m_base(0) {}
  ~Caller() { delBase(); }
  void set(Base *b) { delBase(); m_base = b; }
  void reset() { m_base = 0; }
  unsigned int UIntMethodCall(unsigned int x) { return m_base-&gt;UIntMethod(x); }

private:
  Base *m_base;
  void delBase() { delete m_base; m_base = 0; }
};
</pre>
</div>

<p>
The director feature is turned off by default and the following simple interface file shows how directors are enabled
for the class <tt>Base</tt>.
</p>

<div class="code">
<pre>
/* File : example.i */
%module(directors="1") example
%{
#include "example.h"
%}

%feature("director") Base;

%include "example.h"
</pre>
</div>

<p>
The following is a C# class inheriting from <tt>Base</tt>:
</p>

<div class="code">
<pre>
public class CSharpDerived : Base
{
  public override uint UIntMethod(uint x)
  {
    Console.WriteLine("CSharpDerived - UIntMethod({0})", x);
    return x;
  }
}
</pre>
</div>

<p>
The <tt>Caller</tt> class can demonstrate the <tt>UIntMethod</tt> method being called from unmanaged code using the following C# code:
</p>

<div class="targetlang">
<pre>
public class runme
{
  static void Main() 
  {
    Caller myCaller = new Caller();

    // Test pure C++ class
    using (Base myBase = new Base())
    {
      makeCalls(myCaller, myBase);
    }

    // Test director / C# derived class
    using (Base myBase = new CSharpDerived())
    {
      makeCalls(myCaller, myBase);
    }
  }

  static void makeCalls(Caller myCaller, Base myBase)
  {
    myCaller.set(myBase);
    myCaller.UIntMethodCall(123);
    myCaller.reset();
  }
}
</pre>
</div>

<p>
If the above is run, the output is then:
</p>

<div class="shell">
<pre>
Base - UIntMethod(123)
CSharpDerived - UIntMethod(123)
</pre>
</div>

<H3><a name="csharp_directors_implementation"></a>18.5.2 Directors implementation</H3>


<p>
The previous section demonstrated a simple example where the virtual <tt>UIntMethod</tt> method was called from
C++ code, even when the overridden method is implemented in C#.
The intention of this section is to gain an insight into how the director feature works. 
It shows the generated code for the two virtual methods, <tt>UIntMethod</tt> and <tt>BaseBoolMethod</tt>,
when the director feature is enabled for the <tt>Base</tt> class.
</p>

<p>
Below is the generated C# <tt>Base</tt> director class.
</p>

<div class="code">
<pre>
using System;
using System.Runtime.InteropServices;

public class Base : IDisposable {
  private HandleRef swigCPtr;
  protected bool swigCMemOwn;

  internal Base(IntPtr cPtr, bool cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = new HandleRef(this, cPtr);
  }

  internal static HandleRef getCPtr(Base obj) {
    return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr;
  }

  ~Base() {
    Dispose();
  }

  public virtual void Dispose() {
    lock(this) {
      if(swigCPtr.Handle != IntPtr.Zero &amp;&amp; swigCMemOwn) {
        swigCMemOwn = false;
        examplePINVOKE.delete_Base(swigCPtr);
      }
      swigCPtr = new HandleRef(null, IntPtr.Zero);
      GC.SuppressFinalize(this);
    }
  }

  public virtual uint UIntMethod(uint x) {
    uint ret = examplePINVOKE.Base_UIntMethod(swigCPtr, x);
    return ret;
  }

  public virtual void BaseBoolMethod(Base b, bool flag) {
    examplePINVOKE.Base_BaseBoolMethod(swigCPtr, Base.getCPtr(b), flag);
    if (examplePINVOKE.SWIGPendingException.Pending)
      throw examplePINVOKE.SWIGPendingException.Retrieve();
  }

  public Base() : this(examplePINVOKE.new_Base(), true) {
    SwigDirectorConnect();
  }

  private void SwigDirectorConnect() {
    if (SwigDerivedClassHasMethod("UIntMethod", swigMethodTypes0))
      swigDelegate0 = new SwigDelegateBase_0(SwigDirectorUIntMethod);
    if (SwigDerivedClassHasMethod("BaseBoolMethod", swigMethodTypes1))
      swigDelegate1 = new SwigDelegateBase_1(SwigDirectorBaseBoolMethod);
    examplePINVOKE.Base_director_connect(swigCPtr, swigDelegate0, swigDelegate1);
  }

  private bool SwigDerivedClassHasMethod(string methodName, Type[] methodTypes) {
    System.Reflection.MethodInfo methodInfo = this.GetType().GetMethod(methodName, methodTypes);
    bool hasDerivedMethod = methodInfo.DeclaringType.IsSubclassOf(typeof(Base));
    return hasDerivedMethod;
  }

  private uint SwigDirectorUIntMethod(uint x) {
    return UIntMethod(x);
  }

  private void SwigDirectorBaseBoolMethod(IntPtr b, bool flag) {
    BaseBoolMethod(new Base(b, false), flag);
  }

  internal delegate uint SwigDelegateBase_0(uint x);
  internal delegate void SwigDelegateBase_1(IntPtr b, bool flag);

  private SwigDelegateBase_0 swigDelegate0;
  private SwigDelegateBase_1 swigDelegate1;

  private static Type[] swigMethodTypes0 = new Type[] { typeof(uint) };
  private static Type[] swigMethodTypes1 = new Type[] { typeof(Base), typeof(bool) };
}
</pre>
</div>

<p>
Everything from the <tt>SwigDirectorConnect()</tt> method and below is code that is only generated when
directors are enabled.
The design comprises a C# delegate being initialised for each virtual method on construction of the class.
Let's examine the <tt>BaseBoolMethod</tt>.
</p>

<p>
In the <tt>Base</tt> constructor a call is made to <tt>SwigDirectorConnect()</tt> which contains the initialisation code for all the virtual methods.
It uses a support method, <tt>SwigDerivedClassHasMethod()</tt>, which simply uses reflection to determine if the named method,
BaseBoolMethod, with the list of required parameter types, exists in a subclass.
If it does not exist, the delegate is not initialised as there is no need for unmanaged code to call back into managed C# code.
However, if there is an overridden method in any subclass, the delegate is required. 
It is then initialised to the <tt>SwigDirectorBaseBoolMethod</tt> which in turn will call <tt>BaseBoolMethod</tt> if invoked.
The delegate is not initialised to the <tt>BaseBoolMethod</tt> directly as quite often types will need marshalling from the unmanaged type
to the managed type in which case an intermediary method (<tt>SwigDirectorBaseBoolMethod</tt>) is required for the marshalling.
In this case, the C# <tt>Base</tt> class needs to be created from the unmanaged <tt>IntPtr</tt> type.
</p>

<p>
The last thing that <tt>SwigDirectorConnect()</tt> does is to pass the delegates to the unmanaged code.
It calls the intermediary method <tt>Base_director_connect()</tt> which is really a call to the C function <tt>CSharp_Base_director_connect()</tt>.
This method simply maps each C# delegate onto a C function pointer.
</p>

<div class="code">
<pre>
SWIGEXPORT void SWIGSTDCALL CSharp_Base_director_connect(void *objarg, 
                                        SwigDirector_Base::SWIG_Callback0_t callback0,
                                        SwigDirector_Base::SWIG_Callback1_t callback1) {
  Base *obj = (Base *)objarg;
  SwigDirector_Base *director = dynamic_cast&lt;SwigDirector_Base *&gt;(obj);
  if (director) {
    director-&gt;swig_connect_director(callback0, callback1);
  }
}

class SwigDirector_Base : public Base, public Swig::Director {
public:
    SwigDirector_Base();
    virtual unsigned int UIntMethod(unsigned int x);
    virtual ~SwigDirector_Base();
    virtual void BaseBoolMethod(Base const &amp;b, bool flag);

    typedef unsigned int (SWIGSTDCALL* SWIG_Callback0_t)(unsigned int);
    typedef void (SWIGSTDCALL* SWIG_Callback1_t)(void *, unsigned int);
    void swig_connect_director(SWIG_Callback0_t callbackUIntMethod, 
                               SWIG_Callback1_t callbackBaseBoolMethod);

private:
    SWIG_Callback0_t swig_callbackUIntMethod;
    SWIG_Callback1_t swig_callbackBaseBoolMethod;
    void swig_init_callbacks();
};

void SwigDirector_Base::swig_connect_director(SWIG_Callback0_t callbackUIntMethod, 
                                              SWIG_Callback1_t callbackBaseBoolMethod) {
  swig_callbackUIntMethod = callbackUIntMethod;
  swig_callbackBaseBoolMethod = callbackBaseBoolMethod;
}
</pre>
</div>

<p>
Note that for each director class SWIG creates an unmanaged director class for making the callbacks. For example <tt>Base</tt> has <tt>SwigDirector_Base</tt> and <tt>SwigDirector_Base</tt>
is derived from <tt>Base</tt>.
Should a C# class be derived from <tt>Base</tt>, the underlying C++ <tt>SwigDirector_Base</tt> is created rather than <tt>Base</tt>.
The <tt>SwigDirector_Base</tt> class then implements all the virtual methods, redirecting calls up to managed code if the callback/delegate is non-zero.
The implementation of <tt>SwigDirector_Base::BaseBoolMethod</tt> shows this - the callback is made by invoking the <tt>swig_callbackBaseBoolMethod</tt> function pointer:
</p>

<div class="code">
<pre>
void SwigDirector_Base::BaseBoolMethod(Base const &amp;b, bool flag) {
  void * jb = 0 ;
  unsigned int jflag  ;
  
  if (!swig_callbackBaseBoolMethod) {
    Base::BaseBoolMethod(b,flag);
    return;
  } else {
    jb = (Base *) &amp;b; 
    jflag = flag;
    swig_callbackBaseBoolMethod(jb, jflag);
  }
}
</pre>
</div>

<H3><a name="csharp_director_caveats"></a>18.5.3 Director caveats</H3>


<p>
There is a subtle gotcha with directors.
If default parameters are used, it is recommended to follow a pattern of always calling a single method in any C# derived class.
An example will clarify this and the reasoning behind the recommendation. Consider the following C++ class wrapped as a director class:
</p>

<div class="code">
<pre>
class Defaults {
public:
  virtual ~Defaults();
  virtual void DefaultMethod(int a=-100);
};
</pre>
</div>

<p>
Recall that C++ methods with default parameters generate overloaded methods for each defaulted parameter, so a C# derived class can be created
with two <tt>DefaultMethod</tt> override methods:
</p>

<div class="code">
<pre>
public class CSharpDefaults : Defaults
{
  public override void DefaultMethod()
  {
    DefaultMethod(-100); // note C++ default value used
  }
  public override void DefaultMethod(int x)
  {
  }
}
</pre>
</div>

<p>
It may not be clear at first, but should a user intend to call <tt>CSharpDefaults.DefaultMethod()</tt> from C++, a call is actually made to <tt>CSharpDefaults.DefaultMethod(int)</tt>.
This is because the initial call is made in C++ and therefore the <tt>DefaultMethod(int)</tt> method will be called as is expected with C++ calls to methods with defaults,
with the default being set to -100.
The callback/delegate matching this method is of course the overloaded method <tt>DefaultMethod(int)</tt>.
However, a call from C# to <tt>CSharpDefaults.DefaultMethod()</tt> will of course call this exact method and in order for behaviour to be consistent with calls from C++, the implementation
should pass the call on to <tt>CSharpDefaults.DefaultMethod(int)</tt>using the C++ default value, as shown above.
</p>

<H2><a name="csharp_typemap_examples"></a>18.6 C# Typemap examples</H2>


This section includes a few examples of typemaps.  For more examples, you
might look at the files "<tt>csharp.swg</tt>" and "<tt>typemaps.i</tt>" in
the SWIG library.


<H3><a name="csharp_memory_management_member_variables"></a>18.6.1 Memory management when returning references to member variables</H3>


<p>
This example shows how to prevent premature garbage collection of objects when the underlying C++ class returns a pointer or reference to a member variable.
The example is a direct equivalent to this <a href="Java.html#java_memory_management_objects">Java equivalent</a>.
</p>

<p>
Consider the following C++ code:
</p>

<div class="code">
<pre>
struct Wheel {
  int size;
  Wheel(int sz) : size(sz) {}
};

class Bike {
  Wheel wheel;
public:
  Bike(int val) : wheel(val) {}
  Wheel&amp; getWheel() { return wheel; }
};
</pre>
</div>

<p>
and the following usage from C# after running the code through SWIG:
</p>


<div class="code">
<pre>
      Wheel wheel = new Bike(10).getWheel();
      Console.WriteLine("wheel size: " + wheel.size);
      // Simulate a garbage collection
      System.GC.Collect();
      System.GC.WaitForPendingFinalizers();
      Console.WriteLine("wheel size: " + wheel.size);
</pre>
</div>

<p>
Don't be surprised that if the resulting output gives strange results such as...
</p>

<div class="shell">
<pre>
wheel size: 10
wheel size: 135019664
</pre>
</div>

<p>
What has happened here is the garbage collector has collected the <tt>Bike</tt> instance as it doesn't think it is needed any more.
The proxy instance, <tt>wheel</tt>, contains a reference to memory that was deleted when the <tt>Bike</tt> instance was collected.
In order to prevent the garbage collector from collecting the <tt>Bike</tt> instance a reference to the <tt>Bike</tt> must
be added to the <tt>wheel</tt> instance. You can do this by adding the reference when the <tt>getWheel()</tt> method
is called using the following typemaps.
</p>


<div class="code">
<pre>
%typemap(cscode) Wheel %{
  // Ensure that the GC doesn't collect any Bike instance set from C#
  private Bike bikeReference;
  internal void addReference(Bike bike) {
    bikeReference = bike;
  }
%}

// Add a C# reference to prevent premature garbage collection and resulting use
// of dangling C++ pointer. Intended for methods that return pointers or
// references to a member variable.
%typemap(csout, excode=SWIGEXCODE) Wheel&amp; getWheel {
    IntPtr cPtr = $imcall;$excode
    $csclassname ret = null;
    if (cPtr != IntPtr.Zero) {
      ret = new $csclassname(cPtr, $owner);
      ret.addReference(this);
    }
    return ret;
  }
</pre>
</div>

<p>
The code in the first typemap gets added to the <tt>Wheel</tt> proxy class.
The code in the second typemap constitutes the bulk of the code in the generated <tt>getWheel()</tt> function:
</p>

<div class="code">
<pre>
public class Wheel : IDisposable {
  ...
  // Ensure that the GC doesn't collect any Bike instance set from C#
  private Bike bikeReference;
  internal void addReference(Bike bike) {
    bikeReference = bike;
  }
}

public class Bike : IDisposable {
  ...
  public Wheel getWheel() {
    IntPtr cPtr = examplePINVOKE.Bike_getWheel(swigCPtr);
    Wheel ret = null;
    if (cPtr != IntPtr.Zero) {
      ret = new Wheel(cPtr, false);
      ret.addReference(this);
    }
    return ret;
  }
}
</pre>
</div>

<p>
Note the <tt>addReference</tt> call.
</p>

<H3><a name="csharp_memory_management_objects"></a>18.6.2 Memory management for objects passed to the C++ layer</H3>


<p>
The example is a direct equivalent to this <a href="Java.html#java_memory_management_objects">Java equivalent</a>.
Managing memory can be tricky when using C++ and C# proxy classes.
The previous example shows one such case and this example looks at memory management for a class passed to a C++ method which expects the object to remain in scope
after the function has returned. Consider the following two C++ classes:
</p>

<div class="code">
<pre>
struct Element {
  int value;
  Element(int val) : value(val) {}
};
class Container {
  Element* element;
public:
  Container() : element(0) {}
  void setElement(Element* e) { element = e; }
  Element* getElement() { return element; }
};
</pre>
</div>

<p>
and usage from C++
</p>

<div class="code">
<pre>
    Container container;
    Element element(20);
    container.setElement(&amp;element);
    cout &lt;&lt; "element.value: " &lt;&lt; container.getElement()-&gt;value &lt;&lt; endl;
</pre>
</div>

<p>
and more or less equivalent usage from C#
</p>

<div class="code">
<pre>
      Container container = new Container();
      Element element = new Element(20);
      container.setElement(element);
</pre>
</div>

<p>
The C++ code will always print out 20, but the value printed out may not be this in the C# equivalent code.
In order to understand why, consider a garbage collection occuring...
</p>

<div class="code">
<pre>
      Container container = new Container();
      Element element = new Element(20);
      container.setElement(element);
      Console.WriteLine("element.value: " + container.getElement().value);
      // Simulate a garbage collection
      System.GC.Collect();
      System.GC.WaitForPendingFinalizers();
      Console.WriteLine("element.value: " + container.getElement().value);
</pre>
</div>

<p>
The temporary element created with <tt>new Element(20)</tt> could get garbage collected
which ultimately means the <tt>container</tt> variable is holding a dangling pointer, thereby printing out any old random value instead of the expected value of 20.
One solution is to add in the appropriate references in the C# layer...
</p>

<div class="code">
<pre>
public class Container : IDisposable {

  ...

  // Ensure that the GC doesn't collect any Element set from C#
  // as the underlying C++ class stores a shallow copy
  private Element elementReference;
  private HandleRef getCPtrAndAddReference(Element element) {
    elementReference = element;
    return Element.getCPtr(element);
  }

  public void setElement(Element e) {
    examplePINVOKE.Container_setElement(swigCPtr, getCPtrAndAddReference(e));
  }
}
</pre>
</div>

<p>
The following typemaps will generate the desired code.
The 'csin' typemap matches the input parameter type for the <tt>setElement</tt> method.
The 'cscode' typemap simply adds in the specified code into the C# proxy class.
</p>

<div class="code">
<pre>
%typemap(csin) Element *e "getCPtrAndAddReference($csinput)"

%typemap(cscode) Container %{
  // Ensure that the GC doesn't collect any Element set from C#
  // as the underlying C++ class stores a shallow copy
  private Element elementReference;
  private HandleRef getCPtrAndAddReference(Element element) {
    elementReference = element;
    return Element.getCPtr(element);
  }
%}
</pre>
</div>


<H3><a name="csharp_date_marshalling"></a>18.6.3 Date marshalling using the csin typemap and associated attributes</H3>


<p>
The <a href="Java.html#nan_exception_typemap">NaN Exception example</a> is a simple example of the "javain" typemap and its 'pre' attribute.
This example demonstrates how a C++ date class, say <tt>CDate</tt>, can be mapped onto the standard .NET date class,
<tt>System.DateTime</tt> by using the 'pre', 'post' and 'pgcppname' attributes of the "csin" typemap (the C# equivalent to the "javain" typemap).
The example is an equivalent to the <a href="Java.html#java_date_marshalling">Java Date marshalling example</a>.
The idea is that the <tt>System.DateTime</tt> is used wherever the C++ API uses a <tt>CDate</tt>.
Let's assume the code being wrapped is as follows:
</p>

<div class="code">
<pre>
class CDate {
public:
  CDate();
  CDate(int year, int month, int day);
  int getYear();
  int getMonth();
  int getDay();
  ...
};
struct Action {
  static int doSomething(const CDate &amp;dateIn, CDate &amp;dateOut);
  Action(const CDate &amp;date, CDate &amp;dateOut);
};
</pre>
</div>

<p>
Note that <tt>dateIn</tt> is const and therefore read only and <tt>dateOut</tt> is a non-const output type.
</p>

<p>
First let's look at the code that is generated by default, where the C# proxy class <tt>CDate</tt> is used in the proxy interface:
</p>

<div class="code">
<pre>
public class Action : IDisposable {
  ...
  public Action(CDate dateIn, CDate dateOut) 
      : this(examplePINVOKE.new_Action(CDate.getCPtr(dateIn), CDate.getCPtr(dateOut)), true) {
    if (examplePINVOKE.SWIGPendingException.Pending) 
      throw examplePINVOKE.SWIGPendingException.Retrieve();
  }

  public int doSomething(CDate dateIn, CDate dateOut) {
    int ret = examplePINVOKE.Action_doSomething(swigCPtr, 
                                                CDate.getCPtr(dateIn), 
                                                CDate.getCPtr(dateOut));
    if (examplePINVOKE.SWIGPendingException.Pending) 
      throw examplePINVOKE.SWIGPendingException.Retrieve();
    return ret;
  }
}
</pre>
</div>

<p>
The <tt>CDate &amp;</tt> and <tt>const CDate &amp;</tt> C# code is generated from the following two default typemaps:
</p>

<div class="code">
<pre>
%typemap(cstype) SWIGTYPE &amp; "$csclassname"
%typemap(csin) SWIGTYPE &amp; "$csclassname.getCPtr($csinput)"
</pre>
</div>

<p>
where '$csclassname' is translated into the proxy class name, <tt>CDate</tt> and '$csinput' is translated into the name of the parameter, eg <tt>dateIn</tt>.
From C#, the intention is then to call into a modifed API with something like:
</p>

<div class="code">
<pre>
System.DateTime dateIn = new System.DateTime(2011, 4, 13);
System.DateTime dateOut = new System.DateTime();

// Note in calls below, dateIn remains unchanged and dateOut 
// is set to a new value by the C++ call
Action action = new Action(dateIn, out dateOut);
dateIn = new System.DateTime(2012, 7, 14);
</pre>
</div>

<p>
To achieve this mapping, we need to alter the default code generation slightly so that at the C# layer, 
a <tt>System.DateTime</tt> is converted into a <tt>CDate</tt>. 
The intermediary layer will still take a pointer to the underlying <tt>CDate</tt> class.
The typemaps to achieve this are shown below.
</p>

<div class="code">
<pre>
%typemap(cstype) const CDate&amp; "System.DateTime"
%typemap(csin, 
         pre="    CDate temp$csinput = new CDate($csinput.Year, $csinput.Month, $csinput.Day);"
        ) const CDate &amp;
         "$csclassname.getCPtr(temp$csinput)"

%typemap(cstype) CDate&amp; "out System.DateTime"
%typemap(csin, 
         pre="    CDate temp$csinput = new CDate();", 
         post="      $csinput = new System.DateTime(temp$csinput.getYear(),"
              " temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);", 
         cshin="out $csinput"
        ) CDate &amp;
         "$csclassname.getCPtr(temp$csinput)"

</pre>
</div>

<p>
The resulting generated proxy code in the <tt>Action</tt> class follows:
 </p>

<div class="code">
<pre>
public class Action : IDisposable {
  ...
  public int doSomething(System.DateTime dateIn, out System.DateTime dateOut) {
    CDate tempdateIn = new CDate(dateIn.Year, dateIn.Month, dateIn.Day);
    CDate tempdateOut = new CDate();
    try {
      int ret = examplePINVOKE.Action_doSomething(swigCPtr, 
                                                  CDate.getCPtr(tempdateIn), 
                                                  CDate.getCPtr(tempdateOut));
      if (examplePINVOKE.SWIGPendingException.Pending) 
        throw examplePINVOKE.SWIGPendingException.Retrieve();
      return ret;
    } finally {
      dateOut = new System.DateTime(tempdateOut.getYear(), 
                                    tempdateOut.getMonth(), tempdateOut.getDay(), 0, 0, 0);
    }
  }

  static private IntPtr SwigConstructAction(System.DateTime dateIn, out System.DateTime dateOut) {
    CDate tempdateIn = new CDate(dateIn.Year, dateIn.Month, dateIn.Day);
    CDate tempdateOut = new CDate();
    try {
      return examplePINVOKE.new_Action(CDate.getCPtr(tempdateIn), CDate.getCPtr(tempdateOut));
    } finally {
      dateOut = new System.DateTime(tempdateOut.getYear(), 
                                    tempdateOut.getMonth(), tempdateOut.getDay(), 0, 0, 0);
    }
  }

  public Action(System.DateTime dateIn, out System.DateTime dateOut) 
      : this(Action.SwigConstructAction(dateIn, out dateOut), true) {
    if (examplePINVOKE.SWIGPendingException.Pending) 
      throw examplePINVOKE.SWIGPendingException.Retrieve();
  }
}
</pre>
</div>

<p>
A few things to note:
</p>
<ul>
  <li> The "cstype" typemap has changed the parameter type to <tt>System.DateTime</tt> instead of the default generated <tt>CDate</tt> proxy.
  <li> The non-const <tt>CDate &amp;</tt> type is marshalled as a reference parameter in C# as the date cannot be explicitly set once the object has been created, so a new object is created instead.
  <li> The code in the 'pre' attribute appears before the intermediary call (<tt>examplePINVOKE.new_Action</tt> / <tt>examplePINVOKE.Action_doSomething</tt>).
  <li> The code in the 'post' attribute appears after the intermediary call.
  <li> A try .. finally block is generated with the intermediary call in the try block and 'post' code in the finally block.
  The alternative of just using a temporary variable for the return value from the intermediary call and the 'post' code being inserted before the
  return statement is not possible given that the intermediary call and method return comes from a single source (the "csout" typemap).
  <li> The temporary variables in the "csin" typemaps are called <tt>temp$csin</tt>, where "$csin" is replaced with the parameter name.
  "$csin" is used to mangle the variable name so that more than one <tt>CDate &amp;</tt> type can be used as a parameter in a method, otherwise two or 
  more local variables with the same name would be generated.
  <li> The use of the "csin" typemap causes a constructor helper function (<tt>SwigConstructAction</tt>) to be generated.
  This allows C# code to be called before the intermediary call made in the constructor initialization list.
  <li> The 'cshin' attribute is required for the <tt>SwigConstructAction</tt> constructor helper function so that the 2nd parameter is declared as <tt>out dateOut</tt> instead of just <tt>dateOut</tt>.
</ul>

<p>
So far we have considered the date as an input only and an output only type.
Now let's consider <tt>CDate *</tt> used as an input/output type. Consider the following C++ function which modifies the date passed in:
</p>

<div class="code">
<pre>
void addYears(CDate *pDate, int years) {
  *pDate = CDate(pDate-&gt;getYear() + years, pDate-&gt;getMonth(), pDate-&gt;getDay());
}
</pre>
</div>

<p>
If usage of <tt>CDate *</tt> commonly follows this input/output pattern, usage from C# like the following
</p>

<div class="code">
<pre>
System.DateTime christmasEve = new System.DateTime(2000, 12, 24);
example.addYears(ref christmasEve, 10); // christmasEve now contains 2010-12-24
</pre>
</div>

<p>
will be possible with the following <tt>CDate *</tt> typemaps
</p>

<div class="code">
<pre>
%typemap(cstype, out="System.DateTime") CDate * "ref System.DateTime"

%typemap(csin,
         pre="    CDate temp$csinput = new CDate($csinput.Year, $csinput.Month, $csinput.Day);",
         post="      $csinput = new System.DateTime(temp$csinput.getYear(),"
              " temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);", 
         cshin="ref $csinput"
        ) CDate *
         "$csclassname.getCPtr(temp$csinput)"
</pre>
</div>

<p>
Globals are wrapped by the module class and for a module called example, the typemaps result in the following code:
</p>

<div class="code">
<pre>
public class example {
  public static void addYears(ref System.DateTime pDate, int years) {
    CDate temppDate = new CDate(pDate.Year, pDate.Month, pDate.Day);
    try {
      examplePINVOKE.addYears(CDate.getCPtr(temppDate), years);
    } finally {
      pDate = new System.DateTime(temppDate.getYear(), temppDate.getMonth(), temppDate.getDay(), 0, 0, 0);
    }
  }
  ...
}
</pre>
</div>

<p>
The following typemap is the same as the previous but demonstrates how a using block can be used for the temporary variable.
The only change to the previous typemap is the introduction of the 'terminator' attribute to terminate the <tt>using</tt> block.
The <tt>subtractYears</tt> method is nearly identical to the above <tt>addYears</tt> method.
</p>

<div class="code">
<pre>
%typemap(csin,
         pre="    using (CDate temp$csinput = new CDate($csinput.Year, $csinput.Month, $csinput.Day)) {",
         post="      $csinput = new System.DateTime(temp$csinput.getYear(),"
              " temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);", 
         terminator="    } // terminate temp$csinput using block",
         cshin="ref $csinput"
        ) CDate *
         "$csclassname.getCPtr(temp$csinput)"

void subtractYears(CDate *pDate, int years) {
  *pDate = CDate(pDate-&gt;getYear() - years, pDate-&gt;getMonth(), pDate-&gt;getDay());
}
</pre>
</div>

<p>
The resulting generated code shows the termination of the <tt>using</tt> block:
</p>

<div class="code">
<pre>
public class example {
  public static void subtractYears(ref System.DateTime pDate, int years) {
    using (CDate temppDate = new CDate(pDate.Year, pDate.Month, pDate.Day)) {
    try {
      examplePINVOKE.subtractYears(CDate.getCPtr(temppDate), years);
    } finally {
      pDate = new System.DateTime(temppDate.getYear(), temppDate.getMonth(), temppDate.getDay(), 0, 0, 0);
    }
    } // terminate temppDate using block
  }
  ...
}
</pre>
</div>

<H3><a name="csharp_date_properties"></a>18.6.4 A date example demonstrating marshalling of C# properties</H3>


<p>
The previous section looked at converting a C++ date class to <tt>System.DateTime</tt> for parameters.
This section extends this idea so that the correct marshalling is obtained when wrapping C++ variables.
Consider the same <tt>CDate</tt> class from the previous section and a global variable:
</p>

<div class="code">
<pre>
CDate ImportantDate = CDate(1999, 12, 31);
</pre>
</div>

<p>
The aim is to use <tt>System.DateTime</tt> from C# when accessing this date as shown in the following usage where the module name is 'example':
</p>

<div class="code">
<pre>
example.ImportantDate = new System.DateTime(2000, 11, 22);
System.DateTime importantDate = example.ImportantDate;
Console.WriteLine("Important date: " + importantDate);
</pre>
</div>

<p>
When SWIG wraps a variable that is a class/struct/union, it is wrapped using a pointer to the type for the reasons given in <a href="SWIG.html#SWIG_structure_data_members">Stucture data members</a>.
The typemap type required is thus <tt>CDate *</tt>. Given that the previous section already designed <tt>CDate *</tt> typemaps, we'll use those same typemaps plus the 'csvarin' and 'csvarout' typemaps.

<div class="code">
<pre>
%typemap(cstype, out="System.DateTime") CDate * "ref System.DateTime"

%typemap(csin,
         pre="    CDate temp$csinput = new CDate($csinput.Year, $csinput.Month, $csinput.Day);",
         post="      $csinput = new System.DateTime(temp$csinput.getYear(),"
              " temp$csinput.getMonth(), temp$csinput.getDay(), 0, 0, 0);", 
         cshin="ref $csinput"
        ) CDate *
         "$csclassname.getCPtr(temp$csinput)"

%typemap(csvarin, excode=SWIGEXCODE2) CDate * %{
    /* csvarin typemap code */
    set {
      CDate temp$csinput = new CDate($csinput.Year, $csinput.Month, $csinput.Day);
      $imcall;$excode
    } %}

%typemap(csvarout, excode=SWIGEXCODE2) CDate * %{
    /* csvarout typemap code */
    get {
      IntPtr cPtr = $imcall;
      CDate tempDate = (cPtr == IntPtr.Zero) ? null : new CDate(cPtr, $owner);$excode
      return new System.DateTime(tempDate.getYear(), tempDate.getMonth(), tempDate.getDay(),
                                 0, 0, 0);
    } %}
</pre>
</div>

<p>
For a module called example, the typemaps result in the following code:
</p>

<div class="code">
<pre>
public class example {
  public static System.DateTime ImportantDate {
    /* csvarin typemap code */
    set {
      CDate tempvalue = new CDate(value.Year, value.Month, value.Day);
      examplePINVOKE.ImportantDate_set(CDate.getCPtr(tempvalue));
    } 
    /* csvarout typemap code */
    get {
      IntPtr cPtr = examplePINVOKE.ImportantDate_get();
      CDate tempDate = (cPtr == IntPtr.Zero) ? null : new CDate(cPtr, false);
      return new System.DateTime(tempDate.getYear(), tempDate.getMonth(), tempDate.getDay(),
                                 0, 0, 0);
    } 
  }
  ...
}
</pre>
</div>

<p>
Some points to note:
</p>

<ul>
  <li>The property set comes from the 'csvarin' typemap and the property get comes from the 'csvarout' typemap.
  <li>The type used for the property comes from the 'cstype' typemap. This particular example has the 'out' attribute set in the typemap and as it is specified, it is used in preference to the type in the typemap body. This is because the type in the 'out' attribute can never include modifiers such as 'ref', thereby avoiding code such as <tt>public static ref System.DateTime ImportantDate { ...</tt>, which would of course not compile.
  <li>The <tt>$excode</tt> special variable expands to nothing as there are no exception handlers specified in any of the unmanaged code typemaps (in fact the marshalling was done using the default unmanaged code typemaps.)
  <li>The <tt>$imcall</tt> typemap expands to the appropriate intermediary method call in the <tt>examplePINVOKE</tt> class.
  <li>The <tt>$csinput</tt> special variable in the 'csin' typemap always expands to <tt>value</tt> for properties. In this case <tt>$csclassname.getCPtr(temp$csinput)</tt> expands to <tt>CDate.getCPtr(tempvalue)</tt>.
  <li>The 'csin' typemap has 'pre', 'post' and 'cshin' attributes, and these are all ignored in the property set. The code in these attributes must instead be replicated within the 'csvarin' typemap. The line creating the <tt>temp$csinput</tt> variable is such an example; it is identical to what is in the 'pre' attribute.
</ul>


<H3><a name="csharp_partial_classes"></a>18.6.5 Turning wrapped classes into partial classes</H3>


<p>
C# supports the notion of partial classes whereby a class definition can be split into more than one file.
It is possible to turn the wrapped C++ class into a partial C# class using the <tt>csclassmodifiers</tt> typemap.
Consider a C++ class called <tt>ExtendMe</tt>:
</p>

<div class="code">
<pre>
class ExtendMe {
public:
  int Part1() { return 1; }
};
</pre>
</div>

<p>
The default C# proxy class generated is:
</p>

<div class="code">
<pre>
public class ExtendMe : IDisposable {
  ...
  public int Part1() {
    ...
  }
}
</pre>
</div>

<p>
The default csclassmodifiers typemap shipped with SWIG is
</p>

<div class="code">
<pre>
%typemap(csclassmodifiers) SWIGTYPE "public class"
</pre>
</div>

<p>
Note that the type used is the special catch all type <tt>SWIGTYPE</tt>.
If instead we use the following typemap to override this for just the <tt>ExtendMe</tt> class:
</p>

<div class="code">
<pre>
%typemap(csclassmodifiers) ExtendMe "public partial class"
</pre>
</div>

<p>
The C# proxy class becomes a partial class:
</p>

<div class="code">
<pre>
public partial class ExtendMe : IDisposable {
  ...
  public int Part1() {
    ...
  }
}
</pre>
</div>

<p>
You can then of course declare another part of the partial class elsewhere, for example:
</p>

<div class="code">
<pre>
public partial class ExtendMe : IDisposable {
  public int Part2() {
    return 2;
  }
}
</pre>
</div>

<p>
and compile the following code:
</p>

<div class="code">
<pre>
ExtendMe em = new ExtendMe();
Console.WriteLine("part1: {0}", em.Part1());
Console.WriteLine("part2: {0}", em.Part2());
</pre>
</div>

<p>
demonstrating that the class contains methods calling both unmanaged code - <tt>Part1()</tt> and managed code - <tt>Part2()</tt>.
The following example is an alternative approach to adding managed code to the generated proxy class.
</p>

<H3><a name="csharp_extending_proxy_class"></a>18.6.6 Extending proxy classes with additional C# code</H3>


<p>
The previous example showed how to use partial classes to add functionality to a generated C# proxy class.
It is also possible to extend a wrapped struct/class with C/C++ code by using the <a href="SWIGPlus.html#SWIGPlus_class_extension">%extend directive</a>.
A third approach is to add some C# methods into the generated proxy class with the <tt>cscode</tt> typemap.
If we declare the following typemap before SWIG parses the <tt>ExtendMe</tt> class used in the previous example
</p>

<div class="code">
<pre>
%typemap(cscode) ExtendMe %{
  public int Part3() {
    return 3;
  }
%}

</pre>
</div>

<p>
The generated C# proxy class will instead be:
</p>

<div class="code">
<pre>
public class ExtendMe : IDisposable {
  ...
  public int Part3() {
    return 3;
  }
  public int Part1() {
    ...
  }
}
</pre>
</div>

</body>
</html>

