<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>SWIG and C#</title>
<link rel="stylesheet" type="text/css" href="style.css">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body bgcolor="#FFFFFF">
<H1><a name="CSharp">22 SWIG and C#</a></H1>
<!-- INDEX -->
<div class="sectiontoc">
<ul>
<li><a href="#CSharp_introduction">Introduction</a>
<ul>
<li><a href="#CSharp_introduction_swig2_compatibility">SWIG 2 Compatibility</a>
<li><a href="#CSharp_commandline">Additional command line options</a>
</ul>
<li><a href="#CSharp_differences_java">Differences to the Java module</a>
<li><a href="#CSharp_void_pointers">Void pointers</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_multiple_modules">Multiple modules</a>
<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_date_pre_post_directors">Date example demonstrating the 'pre' and 'post' typemap attributes for directors</a>
<li><a href="#CSharp_partial_classes">Turning proxy classes into partial classes</a>
<li><a href="#CSharp_sealed_proxy_class">Turning proxy classes into sealed classes</a>
<li><a href="#CSharp_extending_proxy_class">Extending proxy classes with additional C# code</a>
<li><a href="#CSharp_enum_underlying_type">Underlying type for enums</a>
</ul>
</ul>
</div>
<!-- INDEX -->



<H2><a name="CSharp_introduction">22.1 Introduction</a></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/en-us/library/aa290048(VS.71).aspx">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/Main_Page">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/docs/advanced/pinvoke/">Interop with native libraries</a>.
</p>

<H3><a name="CSharp_introduction_swig2_compatibility">22.1.1 SWIG 2 Compatibility</a></H3>


<p>
In order to minimize name collisions between names generated based on input to SWIG and names used in the generated code from the .NET framework, SWIG 3 fully qualifies the use of all .NET types. Furthermore, SWIG 3 avoids <tt>using</tt> directives in generated code. This breaks backwards compatibility with typemaps, pragmas, etc written for use with SWIG 2 that assume the presence of <tt>using System;</tt> or <tt>using System.Runtime.InteropServices;</tt> directives in the intermediate class imports, module imports, or proxy imports. SWIG 3 supports backwards compatibility though the use of the <tt>SWIG2_CSHARP</tt> macro. If <tt>SWIG2_CSHARP</tt> is defined, SWIG 3 generates <tt>using</tt> directives in the intermediate class, module class, and proxy class code similar to those generated by SWIG 2. This can be done without modifying any of the input code by passing the <tt>-DSWIG2_CSHARP</tt> commandline parameter when executing <tt>swig</tt>.
</p>


<H3><a name="CSharp_commandline">22.1.2 Additional command line options</a></H3>


<p>
The following table lists the additional commandline options available for the C# module. They can also be seen by using: 
</p>

<div class="code"><pre>
swig -csharp -help 
</pre></div>

<table summary="C# specific options">
<tr>
<th>C# specific options</th>
</tr>

<tr>
<td>-dllimport &lt;dl&gt;</td>
<td>Override DllImport attribute name to &lt;dl&gt;</td>
</tr>

<tr>
<td>-namespace &lt;nm&gt;</td>
<td>Generate wrappers into C# namespace &lt;nm&gt;</td>
</tr>

<tr>
<td>-noproxy</td>
<td>Generate the low-level functional interface instead of proxy classes</td>
</tr>

<tr>
<td>-oldvarnames</td>
<td>Old intermediary method names for variable wrappers</td>
</tr>

<tr>
<td>-outfile &lt;file&gt;</td>
<td>Write all C# into a single &lt;file&gt; located in the output directory
</td>
</tr>

</table>

<p>
The -outfile option combines all the generated C# code into a single output file instead of creating multiple C# files.
The default, when this option is not provided, is to generate separate .cs files for the module class,
intermediary class and each of the generated proxy and type wrapper classes.
Note that the file extension (.cs) will not be automatically added and needs to be provided.
Due to possible compiler limits it is not advisable to use <tt>-outfile</tt> for large projects.
</p>

<H2><a name="CSharp_differences_java">22.2 Differences to the Java module</a></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 <a href="SWIGPlus.html#SWIGPlus_nspace">nspace feature</a> is also supported as described in this general section with a C# example.
Unlike Java which requires the use of the -package option when using the <tt>nspace</tt> feature, the -namespace option is not mandatory for C#.
</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
javainterfacecode           -&gt; csinterfacecode
</pre></div>

</li>

<li>
<p>Typemap macros:</p>
<div class="code"><pre>
SWIG_JAVABODY_PROXY         -&gt; SWIG_CSBODY_PROXY
SWIG_JAVABODY_TYPEWRAPPER   -&gt; SWIG_CSBODY_TYPEWRAPPER
</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>Additional typemap attributes:</p>

<p>
The "null" attribute in the "out" typemap can be specified to provide a value for <tt>$null</tt> to expand into for wrapped functions that return non-void. Normally the default value of <tt>0</tt> is used.
For example this is needed if you change the return type to void:
</p>
<div class="code"><pre>
%typemap(ctype) Status "void"
%typemap(out, null="") Status { ... }
</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
$javaclazzname              -&gt; $csclazzname
$javainput                  -&gt; $csinput
$jnicall                    -&gt; $imcall
$javainterfacename          -&gt; $csinterfacename
$&amp;javainterfacename         -&gt; $&amp;csinterfacename
$*javainterfacename         -&gt; $*csinterfacename
</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 "csdirectorin" typemap supports additional optional attributes called '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.
Please see the <a href="#CSharp_date_pre_post_directors">Date marshalling director example</a> for further understanding of the "csdirectorin" 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="global::System.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 global::System.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.
The 'imtype' typemap can also have an optional <tt>directorinattributes</tt> and <tt>directoroutattributes</tt>
typemap attribute which attaches to director delegates, an implementation detail of directors, see <a href="#CSharp_directors_implementation">directors implementation</a>.
Note that there are C# attributes and typemap attributes, don't get confused between the two!!
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="[global::System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPStr)]",
         outattributes="[return: global::System.Runtime.InteropServices.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 {
  ...
  [global::System.Runtime.InteropServices.DllImport("example", EntryPoint="CSharp_GetMsg")]
  [return: global::System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPStr)]
  public static extern String GetMsg();

  [global::System.Runtime.InteropServices.DllImport("example", EntryPoint="CSharp_SetMsg")]
  public static extern void SetMsg([global::System.Runtime.InteropServices.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>

<p>
The <tt>directorinattributes</tt> and <tt>directoroutattributes</tt> typemap attribute are attached to the delegates in the director class, for example, the SwigDelegateBase_0
</p>

</li>

<li>
<p>
Support for attaching C# attributes to wrapped methods, variables and enum values.
This is done using the <tt>%csattributes</tt> feature, see <a href="Customization.html#Customization_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 : global::System.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>

<p>
An example for attaching attributes to the enum and enum values is shown below.
</p>

<div class="code">
<pre>
%typemap(csattributes) Couleur "[global::System.ComponentModel.Description(\"Colours\")]"
%csattributes Rouge "[global::System.ComponentModel.Description(\"Red\")]"
%csattributes Vert "[global::System.ComponentModel.Description(\"Green\")]"
%inline %{
  enum Couleur { Rouge, Orange, Vert };
%}
</pre>
</div>

<p>
which will result in the following C# enum:
</p>

<div class="code">
<pre>
[global::System.ComponentModel.Description("Colours")]
public enum Couleur {
  [global::System.ComponentModel.Description("Red")]
  Rouge,
  Orange,
  [global::System.ComponentModel.Description("Green")]
  Vert
}
</pre>
</div>
</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. This also works with newer versions of Visual Studio if you allow
it to convert the solution to the latest version.
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.
After SWIG has run and both the C# and C/C++ compilers have finished building,
the examples will be run, by either running <tt>runme.exe</tt> or by running
<tt>mono runme.exe</tt> (Mono C# compiler).
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 C# compilers (Mono or Microsoft) can be detected from within a Cygwin or Mingw environment if installed in your path. 

<H2><a name="CSharp_void_pointers">22.3 Void pointers</a></H2>


<p>
By default SWIG treats <tt>void *</tt> as any other pointer and hence marshalls it as a type wrapper class called <tt>SWIGTYPE_p_void</tt>.
If you want to marshall with the .NET <tt>System.IntPtr</tt> type instead, there is a simple set of named typemaps called
<tt>void *VOID_INT_PTR</tt> that can be used.
They can be applied like any other named typemaps:
</p>


<div class="code">
<pre>
%apply void *VOID_INT_PTR { void * }
void * f(void *v);
</pre>
</div>

<H2><a name="CSharp_arrays">22.4 C# Arrays</a></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">22.4.1 The SWIG C arrays library</a></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">22.4.2 Managed arrays using P/Invoke default array marshalling</a></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 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>
[global::System.Runtime.InteropServices.DllImport("example", EntryPoint="CSharp_myArrayCopy")]
public static extern void myArrayCopy([global::System.Runtime.InteropServices.In, global::System.Runtime.InteropServices.MarshalAs(UnmanagedType.LPArray)]int[] jarg1, 
                                      [global::System.Runtime.InteropServices.Out, global::System.Runtime.InteropServices.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 intermediary class method
</p>

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


<H3><a name="CSharp_arrays_pinning">22.4.3 Managed arrays using pinning</a></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((global::System.IntPtr)swig_ptrTo_sourceArray, (global::System.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 intermediary 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>
[global::System.Runtime.InteropServices.DllImport("example", EntryPoint="CSharp_myArrayCopy")]
public static extern void myArrayCopy(global::System.IntPtr jarg1, global::System.IntPtr jarg2, int jarg3);
</pre>
</div>



<H2><a name="CSharp_exceptions">22.5 C# Exceptions</a></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#Customization_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">22.5.1 C# exception example using "check" typemap</a></H3>


<p>
Let's 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">22.5.2 C# exception example using %exception</a></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#Customization_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());
  return $null;
}
%}

%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">22.5.3 C# exception example using exception specifications</a></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">22.5.4 Custom C# ApplicationException example</a></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);

    [global::System.Runtime.InteropServices.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 : global::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">22.6 C# Directors</a></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">22.6.1 Directors example</a></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">22.6.2 Directors implementation</a></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>
public class Base : global::System.IDisposable {
  private global::System.Runtime.InteropServices.HandleRef swigCPtr;
  protected bool swigCMemOwn;

  internal Base(global::System.IntPtr cPtr, bool cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
  }

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

  ~Base() {
    Dispose();
  }

  public virtual void Dispose() {
    lock(this) {
      if(swigCPtr.Handle != global::System.IntPtr.Zero &amp;&amp; swigCMemOwn) {
        swigCMemOwn = false;
        examplePINVOKE.delete_Base(swigCPtr);
      }
      swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
      global::System.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, global::System.global::System.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(global::System.IntPtr b, bool flag) {
    BaseBoolMethod(new Base(b, false), flag);
  }

  public delegate uint SwigDelegateBase_0(uint x);
  public delegate void SwigDelegateBase_1(global::System.IntPtr b, bool flag);

  private SwigDelegateBase_0 swigDelegate0;
  private SwigDelegateBase_1 swigDelegate1;

  private static global::System.Type[] swigMethodTypes0 = new global::System.Type[] { typeof(uint) };
  private static global::System.Type[] swigMethodTypes1 = new global::System.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>

<p>
The delegates from the above example are <tt>public</tt> by default:
</p>

<div class="code">
<pre>
  public delegate uint SwigDelegateBase_0(uint x);
  public delegate void SwigDelegateBase_1(global::System.IntPtr b, bool flag);
</pre>
</div>

<p>
These can be changed if desired via the <tt>csdirectordelegatemodifiers</tt>
<a href="Customization.html#Customization_features">%feature directive</a>.
For example, using <tt>%feature("csdirectordelegatemodifiers") "internal"</tt>
before SWIG parses the Base class will change all the delegates to <tt>internal</tt>:
</p>

<div class="code">
<pre>
  internal delegate uint SwigDelegateBase_0(uint x);
  internal delegate void SwigDelegateBase_1(global::System.IntPtr b, bool flag);
</pre>
</div>

<H3><a name="CSharp_director_caveats">22.6.3 Director caveats</a></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_multiple_modules">22.7 Multiple modules</a></H2>


<p>
When using <a href="Modules.html#Modules">multiple modules</a> it is possible to compile each SWIG generated wrapper
into a different assembly.
However, by default the generated code may not compile if 
generated classes in one assembly use generated classes in another assembly.
The visibility of the
<tt>getCPtr()</tt> and pointer constructor generated from the <tt>csbody</tt> typemaps needs changing.
The default visibility is <tt>internal</tt> but it needs to be <tt>public</tt> for access from a different assembly.
Just changing 'internal' to 'public' in the typemap achieves this.
Two macros are available in <tt>csharp.swg</tt> to make this easier and using them is the preferred approach
over simply copying the typemaps and modifying as this is forward compatible with any changes in
the <tt>csbody</tt> typemap in future versions of SWIG.
The macros are for the proxy and typewrapper classes and can respectively be used to
to make the method and constructor public:
</p>

<div class="code">
<pre>
  SWIG_CSBODY_PROXY(public, public, SWIGTYPE)
  SWIG_CSBODY_TYPEWRAPPER(public, public, public, SWIGTYPE)
</pre>
</div>

<p>
Alternatively, instead of exposing these as public, consider 
using the <tt>[assembly:InternalsVisibleTo("Name")]</tt> attribute available in the .NET framework when you
know which assemblies these can be exposed to.
Another approach would be to make these public, but also to hide them from intellisense by using
the <tt>[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]</tt> attribute
if you don't want users to easily stumble upon these so called 'internal workings' of the wrappers.
</p>

<H2><a name="CSharp_typemap_examples">22.8 C# Typemap examples</a></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">22.8.1 Memory management when returning references to member variables</a></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
  global::System.GC.Collect();
  global::System.GC.WaitForPendingFinalizers();
  global::System.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 {
    global::System.IntPtr cPtr = $imcall;$excode
    $csclassname ret = null;
    if (cPtr != global::System.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 : global::System.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 : global::System.IDisposable {
  ...
  public Wheel getWheel() {
    global::System.IntPtr cPtr = examplePINVOKE.Bike_getWheel(swigCPtr);
    Wheel ret = null;
    if (cPtr != global::System.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">22.8.2 Memory management for objects passed to the C++ layer</a></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 occurring...
</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
  global::System.GC.Collect();
  global::System.GC.WaitForPendingFinalizers();
  global::System.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 : global::System.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;

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

<p>
The following typemaps can be used to generate this code:
</p>

<div class="code">
<pre>
%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;
%}

%typemap(csin,
         post="      elementReference = $csinput;"
         ) Element *e "Element.getCPtr($csinput)"
</pre>
</div>

<p>
The 'cscode' typemap simply adds in the specified code into the C# proxy class.
The 'csin' typemap matches the input parameter type and name for the <tt>setElement</tt> method and
the 'post' typemap attribute allows adding code after the PInvoke call.
The 'post' code is generated into a finally block after the PInvoke call so the resulting code isn't quite
as mentioned earlier, <tt>setElement</tt> is actually:
</p>

<div class="code">
<pre>
  public void setElement(Element e) {
    try {
      examplePINVOKE.Container_setElement(swigCPtr, Element.getCPtr(e));
    } finally {
      elementReference = e;
    }
  }
</pre>
</div>


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


<p>
The <a href="Java.html#Java_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 : global::System.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 modified 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 : global::System.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 global::System.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">22.8.4 A date example demonstrating marshalling of C# properties</a></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">Structure 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 {
      global::System.IntPtr cPtr = $imcall;
      CDate tempDate = (cPtr == global::System.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 {
      global::System.IntPtr cPtr = examplePINVOKE.ImportantDate_get();
      CDate tempDate = (cPtr == global::System.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_date_pre_post_directors">22.8.5 Date example demonstrating the 'pre' and 'post' typemap attributes for directors</a></H3>


<p>
The 'pre' and 'post' attributes in the "csdirectorin" typemap act like the attributes of the same name in the "csin" typemap.
For example if we modify the <a href="#CSharp_date_marshalling">Date marshalling example</a> like this:
</p>

<div class="code"><pre>
class CDate {
  ...
  void setYear(int);
  void setMonth(int);
  void setDay(int);
};
struct Action {
  virtual void someCallback(CDate &amp;date);
  virtual ~Action();
  ...
};
</pre></div>

<p>
and declare <tt>%feature ("director")</tt> for the <tt>Action</tt> class, we would have to define additional
marshalling rules for <tt>CDate &amp;</tt> parameter. The typemap may look like this:
</p>

<div class="code"><pre>
%typemap(csdirectorin,
         pre="System.DateTime temp$iminput = new System.DateTime();",
         post="CDate temp2$iminput = new CDate($iminput, false);\n"
              "temp2$iminput.setYear(tempdate.Year);\n"
              "temp2$iminput.setMonth(tempdate.Month);\n"
              "temp2$iminput.setDay(tempdate.Day);"
         ) CDate &amp;date "out temp$iminput"
</pre></div>

<p>
The generated proxy class code will then contain the following wrapper for calling user-overloaded <tt>someCallback()</tt>:
</p>

<div class="code"><pre>
...
  private void SwigDirectorsomeCallback(global::System.IntPtr date) {
    System.DateTime tempdate = new System.DateTime();
    try {
      someCallback(out tempdate);
    } finally {
      // we create a managed wrapper around the existing C reference, just for convenience
      CDate temp2date = new CDate(date, false);
      temp2date.setYear(tempdate.Year);
      temp2date.setMonth(tempdate.Month);
      temp2date.setDay(tempdate.Day);
    }
  }
...
</pre></div>
<p>
Pay special attention to the memory management issues, using these attributes.
</p>


<H3><a name="CSharp_partial_classes">22.8.6 Turning proxy classes into partial classes</a></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 : global::System.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 : global::System.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 : global::System.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_sealed_proxy_class">22.8.7 Turning proxy classes into sealed classes</a></H3>


<p>
The technique in the previous section can be used to make the proxy class a sealed class.
Consider a C++ class <tt>NotABaseClass</tt> that you don't want to be derived from in C#:
</p>

<div class="code">
<pre>
struct NotABaseClass {
  NotABaseClass();
  ~NotABaseClass();
};
</pre>
</div>

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

<div class="code">
<pre>
public class NotABaseClass : global::System.IDisposable {
  ...
  public virtual void Dispose() {
    ...
  }
}
</pre>
</div>

<p>
The <tt>csclassmodifiers</tt> typemap can be used to modify the class modifiers and
the <tt>csmethodmodifiers</tt> feature can be used on the destructor to modify the proxy's <tt>Dispose</tt> method:
</p>

<div class="code">
<pre>
%typemap(csclassmodifiers) NotABaseClass "public sealed class"
%csmethodmodifiers NotABaseClass::~NotABaseClass "public /*virtual*/";
</pre>
</div>

<p>
The relevant generated code is thus:
</p>

<div class="code">
<pre>
public sealed class NotABaseClass : global::System.IDisposable {
  ...
  public /*virtual*/ void Dispose() {
    ...
  }
}
</pre>
</div>

<p>
Any attempt to derive from the <tt>NotABaseClass</tt> in C# will result in a C# compiler error, for example:
</p>

<div class="code">
<pre>
public class Derived : NotABaseClass {
};
</pre>
</div>
<div class="shell">
<pre>
runme.cs(6,14): error CS0509: `Derived': cannot derive from sealed type `NotABaseClass'
</pre>
</div>

<p>
Finally, if you get a warning about use of 'protected' in the generated base class:
</p>

<div class="shell">
<pre>
NotABaseClass.cs(14,18): warning CS0628: `NotABaseClass.swigCMemOwn': new protected member declared in sealed class
</pre>
</div>

<p>
Either suppress the warning or modify the generated code by copying and tweaking the default
'csbody' typemap code in csharp.swg by modifying swigCMemOwn to not be protected.
</p>

<H3><a name="CSharp_extending_proxy_class">22.8.8 Extending proxy classes with additional C# code</a></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 : global::System.IDisposable {
  ...
  public int Part3() {
    return 3;
  }
  public int Part1() {
    ...
  }
}
</pre>
</div>

<H3><a name="CSharp_enum_underlying_type">22.8.9 Underlying type for enums</a></H3>


<P>
C# enums use int as the underlying type for each enum item.
If you wish to change the underlying type to something else, then use the <tt>csbase</tt> typemap.
For example when your C++ code uses a value larger than int, this is necessary as the C# compiler will not compile values which are too large to fit into an int.
Here is an example:
</p>

<div class="code">
<pre>
%typemap(csbase) BigNumbers "uint"
%inline %{
  enum BigNumbers { big=0x80000000, bigger };
%}
</pre>
</div>

<p>
The generated enum will then use the given underlying type and compile correctly:
</p>

<div class="code">
<pre>
public enum BigNumbers : uint {
  big = 0x80000000,
  bigger
}
</pre>
</div>

</body>
</html>

