<!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">23 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">23.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="https://msdn.microsoft.com/en-us/ie/aa290048(v=vs.94)">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="https://www.mono-project.com/Main_Page/">Mono</a>.
</p>

<p>
SWIG 3 and later requires .NET 2.0 at a minimum.
There are some minor exceptions, where the minimum required is .NET 4.0.
This is when using the <tt>std::complex</tt> and <tt>std::list</tt> STL containers.
</p>

<p>
To get the most out of this chapter an understanding of interop is required.
The <a href="https://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="https://www.mono-project.com/docs/advanced/pinvoke/">Interop with native libraries</a>.
</p>

<H3><a name="CSharp_introduction_swig2_compatibility">23.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">23.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">23.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; csdisposing and csdispose
javadestruct_derived        -&gt; csdisposing_derived and csdispose_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">23.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">23.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">23.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">23.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="https://docs.microsoft.com/en-us/dotnet/framework/interop/default-marshaling-for-arrays">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">23.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="https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/fixed-statement">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">23.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">23.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">23.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">23.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">23.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">23.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">23.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">23.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(SwigDirectorMethodUIntMethod);
    if (SwigDerivedClassHasMethod("BaseBoolMethod", swigMethodTypes1))
      swigDelegate1 = new SwigDelegateBase_1(SwigDirectorMethodBaseBoolMethod);
    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 SwigDirectorMethodUIntMethod(uint x) {
    return UIntMethod(x);
  }

  private void SwigDirectorMethodBaseBoolMethod(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>SwigDirectorMethodBaseBoolMethod</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>SwigDirectorMethodBaseBoolMethod</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">23.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">23.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">23.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">23.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 = 0) : 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">23.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">23.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">23.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">23.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 SwigDirectorMethodsomeCallback(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">23.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">23.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">23.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">23.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>

