Improved C long handling for C#

Defining SWIGWORDSIZE64 now applies the (unsigned)
long long typemaps to (unsigned) long for a better match on systems
where long is 64-bits. A new "Type mapping" section has been added into
the CSharp.html documentation covering this and marshalling of primitive
types. C (unsigned) long handling remains as is by default, that is,
marshall as 32-bit.

The INPUT[], OUTPUT[], INOUT[], FIXED[] typemaps for long and unsigned long
in arrays_csharp.i can now be used and compiled on 64-bit platforms where
sizeof(long) != sizeof(int). Requires SWIGWORDSIZE64 to be defined.

Move SWIGWORDSIZE64 check into fragments

Changes also made so that the C# test-suite passes using:
  env SWIG_FEATURES=-DSWIGWORDSIZE64 make check-csharp-test-suite

See issue #2379
This commit is contained in:
William S Fulton 2023-10-03 18:17:30 +01:00
parent ac06086767
commit fb91d1fa25
13 changed files with 474 additions and 64 deletions

View File

@ -7,6 +7,18 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.2.0 (in progress)
===========================
2023-10-05: wsfulton
[C#] #2379 Defining SWIGWORDSIZE64 now applies the (unsigned)
long long typemaps to (unsigned) long for a better match on systems
where long is 64-bits. A new "Type mapping" section has been added into
the CSharp.html documentation covering this and marshalling of primitive
types. C (unsigned) long handling remains as is by default, that is,
marshall as 32-bit.
The INPUT[], OUTPUT[], INOUT[], FIXED[] typemaps for long and unsigned long
in arrays_csharp.i can now be used and compiled on 64-bit platforms where
sizeof(long) != sizeof(int). Requires SWIGWORDSIZE64 to be defined.
2023-09-27: wsfulton
[Java] #646 #649 Defining SWIGWORDSIZE64 now applies the (unsigned)
long long typemaps to (unsigned) long for a better match on systems

View File

@ -16,7 +16,12 @@
<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_type_mapping">Type mapping</a>
<ul>
<li><a href="#CSharp_primitive_types">Primitive types</a>
<li><a href="#CSharp_other_type_mappings">Other types</a>
<li><a href="#CSharp_void_pointers">Void pointers</a>
</ul>
<li><a href="#CSharp_arrays">C# Arrays</a>
<ul>
<li><a href="#CSharp_arrays_swig_library">The SWIG C arrays library</a>
@ -569,14 +574,313 @@ Windows users can also get the examples working using a
<a href="http://www.cygwin.com">Cygwin</a> or <a href="https://osdn.net/projects/mingw/">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>
<H2><a name="CSharp_type_mapping">23.3 Type mapping</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>.
The marshalling of the types and typemaps used for marshalling across the managed/unmanaged layers are discussed in this section.
The interested reader will find the implementation in the csharp.swg file.
</p>
<H3><a name="CSharp_primitive_types">23.3.1 Primitive types</a></H3>
<p>
Primitive types are marshalled between the unmanaged and managed layers as blittable types.
</p>
<ul>
<li> The first column in the table below shows various C/C++ types that might be parsed by SWIG.
<li> The second column contains the default type provided by the 'ctype' typemap, that is, the type used for marshalling on the C side.
<li> The third column shows the default type provided by both the 'imtype' and the 'cstype' typemaps, that is, the equivalent type on the C# side.
<li> The fourth column shows the size or number of bytes of the 'imtype'/'cstype', which may or may not match the size of the C/C++ type and is discussed next.
</ul>
<table BORDER summary="Default primitive type mappings">
<tr>
<td><b>C/C++ type</b></td>
<td><b>ctype</b></td>
<td><b>imtype/cstype</b></td>
<td><b>Size</b></td>
</tr>
<tr>
<td>bool<br> const bool &amp; </td>
<td>unsigned int</td>
<td>bool</td>
<td>1</td>
</tr>
<tr>
<td>char<br>const char &amp;</td>
<td>char</td>
<td>char</td>
<td>1</td>
</tr>
<tr>
<td>signed char<br>const signed char &amp;</td>
<td>signed char</td>
<td>sbyte</td>
<td>1</td>
</tr>
<tr>
<td>unsigned char<br>const unsigned char &amp;</td>
<td>unsigned char</td>
<td>byte</td>
<td>1</td>
</tr>
<tr>
<td>short<br>const short &amp;</td>
<td>short</td>
<td>short</td>
<td>2</td>
</tr>
<tr>
<td>unsigned short<br> const unsigned short &amp;</td>
<td>unsigned short</td>
<td>ushort</td>
<td>2</td>
</tr>
<tr>
<td>int<br> const int &amp;</td>
<td>int</td>
<td>int</td>
<td>4</td>
</tr>
<tr>
<td>unsigned int<br> const unsigned int &amp;</td>
<td>unsigned int</td>
<td>uint</td>
<td>4</td>
</tr>
<tr>
<td>long<br>const long &amp;</td>
<td>int</td>
<td>int</td>
<td>4</td>
</tr>
<tr>
<td>unsigned long<br>const unsigned long &amp;</td>
<td>unsigned int</td>
<td>uint</td>
<td>4</td>
</tr>
<tr>
<td>long long<br> const long long &amp;</td>
<td>long long</td>
<td>long</td>
<td>8</td>
</tr>
<tr>
<td>unsigned long long<br>const unsigned long long &amp;</td>
<td>unsigned long long</td>
<td>ulong</td>
<td>8</td>
</tr>
<tr>
<td>float<br>const float &amp;</td>
<td>float</td>
<td>float</td>
<td>4</td>
</tr>
<tr>
<td>double<br> const double &amp;</td>
<td>double</td>
<td>double</td>
<td>8</td>
</tr>
<tr>
<td>size_t<br> const size_t &amp;</td>
<td>unsigned int</td>
<td>uint</td>
<td>4</td>
</tr>
</table>
<p>
The size in bytes of the C type, 'ctype', should match the C# type, 'imtype' for blitting across the managed/unmanaged layers.
They do match across the common 32-bit and 64-bit operating systems, Unix, Windows and MacOS, except for the C long/unsigned long and size_t types.
From the table above the default is to handle C long and size_t as a 32-bit (4 byte) type, so large numbers could be truncated on some 64-bit operating systems.
If <tt>SWIGWORDSIZE64</tt> is defined the C long type is instead handled as a 64-bit (8 byte) type, as per the table below.
</p>
<table BORDER summary="SWIGWORDSIZE64 primitive type mappings">
<tr>
<td><b>C/C++ type</b></td>
<td><b>ctype</b></td>
<td><b>imtype/cstype</b></td>
<td><b>Size</b></td>
</tr>
<tr>
<td>long<br>const long &amp;</td>
<td>long long</td>
<td>long</td>
<td>8</td>
</tr>
<tr>
<td>unsigned long<br>const unsigned long &amp;</td>
<td>unsigned long long</td>
<td>ulong</td>
<td>8</td>
</tr>
</table>
<p>
However, truncation may then occur when the C long type is actually 32-bits (4 bytes).
It's best to avoid using C long for portability across different operating systems!
</p>
<p>
If you need to support long on a range of systems where the size of long varies, then steps must be taken before invoking SWIG to determine whether or not to define <tt>SWIGWORDSIZE64</tt> when invoking SWIG.
</p>
<p>
In order to treat the C size_t type as a 64-bit (8 byte) type, apply the 64-bit typemaps as follows:
</p>
<div class="code">
<pre>
%apply unsigned long long { size_t };
%apply const unsigned long long &amp; { const size_t &amp; };
</pre>
</div>
<p>
The net effect then changes from the default shown earlier to:
</p>
<table BORDER summary="size_t long long mappings">
<tr>
<td><b>C/C++ type</b></td>
<td><b>ctype</b></td>
<td><b>imtype/cstype</b></td>
<td><b>Size</b></td>
</tr>
<tr>
<td>size_t<br>const size_t &amp;</td>
<td>unsigned long long</td>
<td>ulong</td>
<td>8</td>
</tr>
</table>
<p>
If you need to support size_t on a range of systems where the size of size_t varies, then steps must be taken before invoking SWIG to determine whether or not to apply the typemaps.
Conditionally applying the typemaps using a macro is easily done. For example define <tt>MY_SIZET_WORDSIZE64</tt> to generate 64-bit (8 byte) handling using the following:
</p>
<div class="code">
<pre>
#if defined(MY_SIZET_WORDSIZE64)
%apply unsigned long long { size_t };
%apply const unsigned long long &amp; { const size_t &amp; };
#endif
</pre>
</div>
<p>
</p>
<H3><a name="CSharp_other_type_mappings">23.3.2 Other types</a></H3>
<p>
The table below shows the equivalent mappings for pointers and strings.
Classes and structs are marshalled using a pointer to the instance of the object.
Note the types in the 'imtype' and 'cstype' typemaps can be different.
</p>
<ul>
<li> The 'imtype' type is used for marshalling across the managed and unmanaged boundary.
<li> The 'cstype' is the final C# proxy or intermediary class type.
<li> In the table below, the 'imtype' type is used for marshalling from the managed to the unmanaged layer.
<li> The 'imtype out' type is used for marshalling from the unmanaged to the managed layer.
</ul>
<table BORDER summary="Other type mappings">
<tr>
<td><b>C/C++ type</b></td>
<td><b>ctype</b></td>
<td><b>imtype</b></td>
<td><b>imtype out</b></td>
<td><b>cstype</b></td>
</tr>
<tr>
<td>char *<br>char []</td>
<td>char *</td>
<td>string</td>
<td>string</td>
<td>string</td>
</tr>
<tr>
<td>void *</td>
<td>void *</td>
<td>System.Runtime.InteropServices.HandleRef</td>
<td>System.IntPtr</td>
<td>SWIGTYPE_p_void</td>
</tr>
</table>
<H3><a name="CSharp_void_pointers">23.3.3 Void pointers</a></H3>
<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>,
as shown in the table in the previous section.
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:
They net effect is then:
</p>
<table BORDER summary="VOID_INT_PTR type mappings">
<tr>
<td><b>C/C++ type</b></td>
<td><b>ctype</b></td>
<td><b>imtype</b></td>
<td><b>imtype out</b></td>
<td><b>cstype</b></td>
</tr>
<tr>
<td>void *VOID_INT_PTR</td>
<td>void *</td>
<td>System.IntPtr</td>
<td>System.IntPtr</td>
<td>System.IntPtr</td>
</tr>
</table>
<p>
This is achieved by applying them like any other named typemaps:
</p>

View File

@ -797,7 +797,12 @@
<li><a href="CSharp.html#CSharp_commandline">Additional command line options</a>
</ul>
<li><a href="CSharp.html#CSharp_differences_java">Differences to the Java module</a>
<li><a href="CSharp.html#CSharp_type_mapping">Type mapping</a>
<ul>
<li><a href="CSharp.html#CSharp_primitive_types">Primitive types</a>
<li><a href="CSharp.html#CSharp_other_type_mappings">Other types</a>
<li><a href="CSharp.html#CSharp_void_pointers">Void pointers</a>
</ul>
<li><a href="CSharp.html#CSharp_arrays">C# Arrays</a>
<ul>
<li><a href="CSharp.html#CSharp_arrays_swig_library">The SWIG C arrays library</a>

View File

@ -591,7 +591,7 @@ public class runme
throw new Exception("verify value failed. Expected: " + expected + " Got: " + got);
}
private void verifyCount(int expected, Klass k) {
int got = li_boost_shared_ptr.use_count(k);
int got = (int)li_boost_shared_ptr.use_count(k);
if (expected != got)
throw new Exception("verify use_count failed. Expected: " + expected + " Got: " + got);
}

View File

@ -5,16 +5,22 @@ using preproc_constants_cNamespace;
// Same as preproc_constants_c.i testcase, but bool types are int instead
public class runme {
static void Main() {
System.Type typeof_long = typeof(int);
System.Type typeof_ulong = typeof(uint);
if (preproc_constants_c.SWIGWORDSIZE64_enabled == 1) {
typeof_long = typeof(long);
typeof_ulong = typeof(ulong);
}
assert( typeof(int) == preproc_constants_c.CONST_INT1.GetType() );
assert( typeof(int) == preproc_constants_c.CONST_INT2.GetType() );
assert( typeof(uint) == preproc_constants_c.CONST_UINT1.GetType() );
assert( typeof(uint) == preproc_constants_c.CONST_UINT2.GetType() );
assert( typeof(uint) == preproc_constants_c.CONST_UINT3.GetType() );
assert( typeof(uint) == preproc_constants_c.CONST_UINT4.GetType() );
assert( typeof(int) == preproc_constants_c.CONST_LONG1.GetType() );
assert( typeof(int) == preproc_constants_c.CONST_LONG2.GetType() );
assert( typeof(int) == preproc_constants_c.CONST_LONG3.GetType() );
assert( typeof(int) == preproc_constants_c.CONST_LONG4.GetType() );
assert( typeof_long == preproc_constants_c.CONST_LONG1.GetType() );
assert( typeof_long == preproc_constants_c.CONST_LONG2.GetType() );
assert( typeof_long == preproc_constants_c.CONST_LONG3.GetType() );
assert( typeof_long == preproc_constants_c.CONST_LONG4.GetType() );
assert( typeof(long) == preproc_constants_c.CONST_LLONG1.GetType() );
assert( typeof(long) == preproc_constants_c.CONST_LLONG2.GetType() );
assert( typeof(long) == preproc_constants_c.CONST_LLONG3.GetType() );
@ -39,8 +45,8 @@ public class runme {
assert( typeof(int) == preproc_constants_c.INT_AND_CHAR.GetType() );
assert( typeof(int) == preproc_constants_c.INT_AND_INT.GetType() );
assert( typeof(uint) == preproc_constants_c.INT_AND_UINT.GetType() );
assert( typeof(int) == preproc_constants_c.INT_AND_LONG.GetType() );
assert( typeof(uint) == preproc_constants_c.INT_AND_ULONG.GetType() );
assert( typeof_long == preproc_constants_c.INT_AND_LONG.GetType() );
assert( typeof_ulong == preproc_constants_c.INT_AND_ULONG.GetType() );
assert( typeof(long) == preproc_constants_c.INT_AND_LLONG.GetType() );
assert( typeof(ulong) == preproc_constants_c.INT_AND_ULLONG.GetType() );
assert( typeof(int ) == preproc_constants_c.BOOL_AND_BOOL.GetType() );

View File

@ -4,16 +4,22 @@ using preproc_constantsNamespace;
public class runme {
static void Main() {
System.Type typeof_long = typeof(int);
System.Type typeof_ulong = typeof(uint);
if (preproc_constants.SWIGWORDSIZE64_enabled == 1) {
typeof_long = typeof(long);
typeof_ulong = typeof(ulong);
}
assert( typeof(int) == preproc_constants.CONST_INT1.GetType() );
assert( typeof(int) == preproc_constants.CONST_INT2.GetType() );
assert( typeof(uint) == preproc_constants.CONST_UINT1.GetType() );
assert( typeof(uint) == preproc_constants.CONST_UINT2.GetType() );
assert( typeof(uint) == preproc_constants.CONST_UINT3.GetType() );
assert( typeof(uint) == preproc_constants.CONST_UINT4.GetType() );
assert( typeof(int) == preproc_constants.CONST_LONG1.GetType() );
assert( typeof(int) == preproc_constants.CONST_LONG2.GetType() );
assert( typeof(int) == preproc_constants.CONST_LONG3.GetType() );
assert( typeof(int) == preproc_constants.CONST_LONG4.GetType() );
assert( typeof_long == preproc_constants.CONST_LONG1.GetType() );
assert( typeof_long == preproc_constants.CONST_LONG2.GetType() );
assert( typeof_long == preproc_constants.CONST_LONG3.GetType() );
assert( typeof_long == preproc_constants.CONST_LONG4.GetType() );
assert( typeof(long) == preproc_constants.CONST_LLONG1.GetType() );
assert( typeof(long) == preproc_constants.CONST_LLONG2.GetType() );
assert( typeof(long) == preproc_constants.CONST_LLONG3.GetType() );
@ -38,8 +44,8 @@ public class runme {
assert( typeof(int) == preproc_constants.INT_AND_CHAR.GetType() );
assert( typeof(int) == preproc_constants.INT_AND_INT.GetType() );
assert( typeof(uint) == preproc_constants.INT_AND_UINT.GetType() );
assert( typeof(int) == preproc_constants.INT_AND_LONG.GetType() );
assert( typeof(uint) == preproc_constants.INT_AND_ULONG.GetType() );
assert( typeof_long == preproc_constants.INT_AND_LONG.GetType() );
assert( typeof_ulong == preproc_constants.INT_AND_ULONG.GetType() );
assert( typeof(long) == preproc_constants.INT_AND_LLONG.GetType() );
assert( typeof(ulong) == preproc_constants.INT_AND_ULLONG.GetType() );
assert( typeof(int ) == preproc_constants.BOOL_AND_BOOL.GetType() );

View File

@ -1,5 +1,8 @@
%module csharp_lib_arrays
// TODO: also test long type for INPUT[], OUTPUT[], INOUT[], FIXED[].
// Will require something clever like detecting sizeof(long) at configure time.
%include "arrays_csharp.i"
%apply int INPUT[] { int* sourceArray }
@ -57,5 +60,3 @@ void myArraySwapUsingFixedArrays( int* array1, int* array2, int nitems ) {
myArraySwap(array1, array2, nitems);
}
%}

View File

@ -120,3 +120,9 @@ enum MyEnum {
kValue = BIT(2)
};
// For detecting when test-suite is run with SWIGWORDSIZE64 defined
#ifdef SWIGWORDSIZE64
#define SWIGWORDSIZE64_enabled 1
#else
#define SWIGWORDSIZE64_enabled 0
#endif

View File

@ -49,8 +49,17 @@
* %csmethodmodifiers myArrayCopy "public unsafe";
* void myArrayCopy( int *sourceArray, int* targetArray, int nitems );
*
* long type
* ---------
* Unlike other primitive types, the sizeof(long) varies considerably from one
* platform to another. The sizeof(long) in the unmanaged layer must match the
* number of bytes used in the managed layer. A check is implemented via the
* "long_check_wordsize" fragment which results in a compile time error upon an
* inconsistent match. Use the SWIGWORDSIZE64 macro to target 64-bit long.
* For easiest portability, avoid using long!
* ----------------------------------------------------------------------------- */
%define CSHARP_ARRAYS( CTYPE, CSTYPE )
// input only arrays
@ -94,16 +103,23 @@ CSHARP_ARRAYS(short, short)
CSHARP_ARRAYS(unsigned short, ushort)
CSHARP_ARRAYS(int, int)
CSHARP_ARRAYS(unsigned int, uint)
// FIXME - on Unix 64 bit, long is 8 bytes but is 4 bytes on Windows 64 bit.
// How can this be handled sensibly?
// See e.g. http://www.xml.com/ldd/chapter/book/ch10.html
CSHARP_ARRAYS(long, int)
CSHARP_ARRAYS(unsigned long, uint)
CSHARP_ARRAYS(long long, long)
CSHARP_ARRAYS(unsigned long long, ulong)
CSHARP_ARRAYS(float, float)
CSHARP_ARRAYS(double, double)
// 32-bit/64-bit architecture specific typemaps - special handling to ensure sizeof(long) on C side matches size used on C# side
#if !defined(SWIGWORDSIZE64)
CSHARP_ARRAYS(long, int)
CSHARP_ARRAYS(unsigned long, uint)
#else
CSHARP_ARRAYS(long, long)
CSHARP_ARRAYS(unsigned long, ulong)
#endif
%typemap(in, fragment="long_check_wordsize") long INPUT[], unsigned long INPUT[] "$1 = $input;"
%typemap(in, fragment="long_check_wordsize") long OUTPUT[], unsigned long OUTPUT[] "$1 = $input;"
%typemap(in, fragment="long_check_wordsize") long INOUT[], unsigned long INOUT[] "$1 = $input;"
// By default C# will marshal bools as 4 bytes
// UnmanagedType.I1 will change this to 1 byte
// FIXME - When running on mono ArraySubType appears to be ignored and bools will be marshalled as 4-byte
@ -169,11 +185,18 @@ CSHARP_ARRAYS_FIXED(short, short)
CSHARP_ARRAYS_FIXED(unsigned short, ushort)
CSHARP_ARRAYS_FIXED(int, int)
CSHARP_ARRAYS_FIXED(unsigned int, uint)
CSHARP_ARRAYS_FIXED(long, int)
CSHARP_ARRAYS_FIXED(unsigned long, uint)
CSHARP_ARRAYS_FIXED(long long, long)
CSHARP_ARRAYS_FIXED(unsigned long long, ulong)
CSHARP_ARRAYS_FIXED(float, float)
CSHARP_ARRAYS_FIXED(double, double)
CSHARP_ARRAYS_FIXED(bool, bool)
// 32-bit/64-bit architecture specific typemaps - special handling to ensure sizeof(long) on C side matches size used on C# side
#ifdef !SWIGWORDSIZE64
CSHARP_ARRAYS_FIXED(long, int)
CSHARP_ARRAYS_FIXED(unsigned long, uint)
#else
CSHARP_ARRAYS_FIXED(long, long)
CSHARP_ARRAYS_FIXED(unsigned long, ulong)
#endif
%typemap(in, fragment="long_check_wordsize") long FIXED[], unsigned long FIXED[] "$1 = $input;"

View File

@ -82,8 +82,8 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
%typemap(ctype) unsigned short, const unsigned short & "unsigned short"
%typemap(ctype) int, const int & "int"
%typemap(ctype) unsigned int, const unsigned int & "unsigned int"
%typemap(ctype) long, const long & "long"
%typemap(ctype) unsigned long, const unsigned long & "unsigned long"
%typemap(ctype) long, const long & "int"
%typemap(ctype) unsigned long, const unsigned long & "unsigned int"
%typemap(ctype) long long, const long long & "long long"
%typemap(ctype) unsigned long long, const unsigned long long & "unsigned long long"
%typemap(ctype) float, const float & "float"
@ -201,9 +201,9 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
%typemap(directorin) short "$input = $1;"
%typemap(directorin) unsigned short "$input = $1;"
%typemap(directorin) int "$input = $1;"
%typemap(directorin) unsigned int "$input = $1;"
%typemap(directorin) unsigned int "$input = (unsigned int)$1;"
%typemap(directorin) long "$input = $1;"
%typemap(directorin) unsigned long "$input = (unsigned long)$1;"
%typemap(directorin) unsigned long "$input = $1;"
%typemap(directorin) long long "$input = $1;"
%typemap(directorin) unsigned long long "$input = $1;"
%typemap(directorin) float "$input = $1;"
@ -246,9 +246,9 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
%typemap(out) short %{ $result = $1; %}
%typemap(out) unsigned short %{ $result = $1; %}
%typemap(out) int %{ $result = $1; %}
%typemap(out) unsigned int %{ $result = $1; %}
%typemap(out) unsigned int %{ $result = (unsigned int)$1; %}
%typemap(out) long %{ $result = $1; %}
%typemap(out) unsigned long %{ $result = (unsigned long)$1; %}
%typemap(out) unsigned long %{ $result = $1; %}
%typemap(out) long long %{ $result = $1; %}
%typemap(out) unsigned long long %{ $result = $1; %}
%typemap(out) float %{ $result = $1; %}
@ -327,7 +327,7 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
%typemap(directorin) const short & "$input = $1;"
%typemap(directorin) const unsigned short & "$input = $1;"
%typemap(directorin) const int & "$input = $1;"
%typemap(directorin) const unsigned int & "$input = $1;"
%typemap(directorin) const unsigned int & "$input = (unsigned int)$1;"
%typemap(directorin) const long & "$input = $1;"
%typemap(directorin) const unsigned long & "$input = $1;"
%typemap(directorin) const long long & "$input = $1;"
@ -373,9 +373,9 @@ SWIGINTERN const char * SWIG_UnpackData(const char *c, void *ptr, size_t sz) {
%typemap(out) const short & %{ $result = *$1; %}
%typemap(out) const unsigned short & %{ $result = *$1; %}
%typemap(out) const int & %{ $result = *$1; %}
%typemap(out) const unsigned int & %{ $result = *$1; %}
%typemap(out) const unsigned int & %{ $result = (unsigned int)*$1; %}
%typemap(out) const long & %{ $result = *$1; %}
%typemap(out) const unsigned long & %{ $result = (unsigned long)*$1; %}
%typemap(out) const unsigned long & %{ $result = *$1; %}
%typemap(out) const long long & %{ $result = *$1; %}
%typemap(out) const unsigned long long & %{ $result = *$1; %}
%typemap(out) const float & %{ $result = *$1; %}
@ -1062,10 +1062,17 @@ SWIG_CSBODY_TYPEWRAPPER(internal, protected, internal, SWIGTYPE)
%pragma(csharp) imclassclassmodifiers="class"
%pragma(csharp) moduleclassmodifiers="public class"
/* Some ANSI C typemaps */
/* 64-bit architecture specific typemaps */
#if defined(SWIGWORDSIZE64)
%apply long long { long };
%apply unsigned long long { unsigned long };
%apply const long long & { const long & };
%apply const unsigned long long & { const unsigned long & };
#endif
%apply unsigned long { size_t };
%apply const unsigned long & { const size_t & };
/* size_t maps to C# 32-bit uint type */
%apply unsigned int { size_t };
%apply const unsigned int & { const size_t & };
/* Array reference typemaps */
%apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) }

View File

@ -74,15 +74,11 @@ INPUT_TYPEMAP(short, short, short)
INPUT_TYPEMAP(unsigned short, unsigned short, ushort)
INPUT_TYPEMAP(int, int, int)
INPUT_TYPEMAP(unsigned int, unsigned int, uint)
INPUT_TYPEMAP(long, long, int)
INPUT_TYPEMAP(unsigned long, unsigned long, uint)
INPUT_TYPEMAP(long long, long long, long)
INPUT_TYPEMAP(unsigned long long, unsigned long long, ulong)
INPUT_TYPEMAP(float, float, float)
INPUT_TYPEMAP(double, double, double)
#undef INPUT_TYPEMAP
/*
OUTPUT typemaps
---------------
@ -153,15 +149,11 @@ OUTPUT_TYPEMAP(short, short, short, INT16_PTR)
OUTPUT_TYPEMAP(unsigned short, unsigned short, ushort, UINT16_PTR)
OUTPUT_TYPEMAP(int, int, int, INT32_PTR)
OUTPUT_TYPEMAP(unsigned int, unsigned int, uint, UINT32_PTR)
OUTPUT_TYPEMAP(long, long, int, INT32_PTR)
OUTPUT_TYPEMAP(unsigned long, unsigned long, uint, UINT32_PTR)
OUTPUT_TYPEMAP(long long, long long, long, INT64_PTR)
OUTPUT_TYPEMAP(unsigned long long, unsigned long long, ulong, UINT64_PTR)
OUTPUT_TYPEMAP(float, float, float, FLOAT_PTR)
OUTPUT_TYPEMAP(double, double, double, DOUBLE_PTR)
#undef OUTPUT_TYPEMAP
%typemap(in) bool *OUTPUT, bool &OUTPUT
%{ *$input = 0;
$1 = ($1_ltype)$input; %}
@ -242,12 +234,47 @@ INOUT_TYPEMAP(short, short, short, INT16_PTR)
INOUT_TYPEMAP(unsigned short, unsigned short, ushort, UINT16_PTR)
INOUT_TYPEMAP(int, int, int, INT32_PTR)
INOUT_TYPEMAP(unsigned int, unsigned int, uint, UINT32_PTR)
INOUT_TYPEMAP(long, long, int, INT32_PTR)
INOUT_TYPEMAP(unsigned long, unsigned long, uint, UINT32_PTR)
INOUT_TYPEMAP(long long, long long, long, INT64_PTR)
INOUT_TYPEMAP(unsigned long long, unsigned long long, ulong, UINT64_PTR)
INOUT_TYPEMAP(float, float, float, FLOAT_PTR)
INOUT_TYPEMAP(double, double, double, DOUBLE_PTR)
#undef INOUT_TYPEMAP
// 32-bit/64-bit architecture specific typemaps - marshal as 32-bit by default
#if !defined(SWIGWORDSIZE64)
INPUT_TYPEMAP(long, int, int)
INPUT_TYPEMAP(unsigned long, unsigned int, uint)
OUTPUT_TYPEMAP(long, int, int, INT32_PTR)
OUTPUT_TYPEMAP(unsigned long, unsigned int, uint, UINT32_PTR)
INOUT_TYPEMAP(long, int, int, INT32_PTR)
INOUT_TYPEMAP(unsigned long, unsigned int, uint, UINT32_PTR)
#else
INPUT_TYPEMAP(long, long long, int)
INPUT_TYPEMAP(unsigned long, unsigned long long, uint)
OUTPUT_TYPEMAP(long, long long, int, INT64_PTR)
OUTPUT_TYPEMAP(unsigned long, unsigned long long, uint, UINT64_PTR)
INOUT_TYPEMAP(long, long long, int, INT64_PTR)
INOUT_TYPEMAP(unsigned long, unsigned long long, uint, UINT64_PTR)
#endif
%typemap(in) long INPUT[] ($*1_ltype tempinput), unsigned long INPUT[] ($*1_ltype tempinput)
%{tempinput = ($*1_ltype)*$input;
$1 = &tempinput;%}
%typemap(in) long OUTPUT[] ($*1_ltype tempoutput), unsigned long OUTPUT[] ($*1_ltype tempoutput)
%{$1 = &tempoutput;%}
%typemap(in) long INOUT[] ($*1_ltype tempinout), unsigned long INOUT[] ($*1_ltype tempinout)
%{tempinout = ($*1_ltype)*$input;
$1 = &tempinout;%}
%typemap(argout) long OUTPUT[], unsigned long OUTPUT[] "*$input = *$1;"
%typemap(argout) long INOUT[], unsigned long INOUT[] "*$input = *$1;"
#undef INPUT_TYPEMAP
#undef OUTPUT_TYPEMAP
#undef INOUT_TYPEMAP

View File

@ -25,23 +25,9 @@
* ----------------------------------------------------------------------------- */
#ifdef SWIGWORDSIZE32
%{
#ifndef LONG_MAX
#include <limits.h>
#endif
#if (__WORDSIZE == 64) || (LONG_MAX != INT_MAX)
# error "SWIG generated code is invalid on this 64-bit architecture, please regenerate without defining SWIGWORDSIZE32 or define SWIGWORDSIZE64"
#endif
%}
%fragment("long_check_wordsize32");
#endif
#ifdef SWIGWORDSIZE64
%{
#ifndef LONG_MAX
#include <limits.h>
#endif
#if (__WORDSIZE == 32) || (LONG_MAX == INT_MAX)
# error "SWIG generated code is invalid on this 32-bit architecture, please regenerate without defining SWIGWORDSIZE64 or define SWIGWORDSIZE32"
#endif
%}
%fragment("long_check_wordsize64");
#endif

View File

@ -92,3 +92,30 @@
%fragment("<memory>", "header") %{
#include <memory>
%}
/* -----------------------------------------------------------------------------
* Other common fragments
* ----------------------------------------------------------------------------- */
%fragment("long_check_wordsize32", "header", fragment="<limits.h>") %{
#if !defined(SWIG_NO_WORDSIZE32_CHECK)
#if (__WORDSIZE == 64) || (LONG_MAX != INT_MAX)
# error "SWIG generated code is invalid on this 64-bit architecture, please regenerate without defining SWIGWORDSIZE32 or define SWIGWORDSIZE64"
#endif
#endif
%}
%fragment("long_check_wordsize64", "header", fragment="<limits.h>") %{
#if !defined(SWIG_NO_WORDSIZE64_CHECK)
#if (__WORDSIZE == 32) || (LONG_MAX == INT_MAX)
# error "SWIG generated code is invalid on this 32-bit architecture, please regenerate without defining SWIGWORDSIZE64 or define SWIGWORDSIZE32"
#endif
#endif
%}
#ifdef SWIGWORDSIZE64
%fragment("long_check_wordsize", "header", fragment="long_check_wordsize64") {}
#else
%fragment("long_check_wordsize", "header", fragment="long_check_wordsize32") {}
#endif