mirror of https://github.com/swig/swig
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:
parent
ac06086767
commit
fb91d1fa25
|
@ -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
|
||||
|
|
|
@ -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 & </td>
|
||||
<td>unsigned int</td>
|
||||
<td>bool</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>char<br>const char &</td>
|
||||
<td>char</td>
|
||||
<td>char</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>signed char<br>const signed char &</td>
|
||||
<td>signed char</td>
|
||||
<td>sbyte</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>unsigned char<br>const unsigned char &</td>
|
||||
<td>unsigned char</td>
|
||||
<td>byte</td>
|
||||
<td>1</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>short<br>const short &</td>
|
||||
<td>short</td>
|
||||
<td>short</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>unsigned short<br> const unsigned short &</td>
|
||||
<td>unsigned short</td>
|
||||
<td>ushort</td>
|
||||
<td>2</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>int<br> const int &</td>
|
||||
<td>int</td>
|
||||
<td>int</td>
|
||||
<td>4</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>unsigned int<br> const unsigned int &</td>
|
||||
<td>unsigned int</td>
|
||||
<td>uint</td>
|
||||
<td>4</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>long<br>const long &</td>
|
||||
<td>int</td>
|
||||
<td>int</td>
|
||||
<td>4</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>unsigned long<br>const unsigned long &</td>
|
||||
<td>unsigned int</td>
|
||||
<td>uint</td>
|
||||
<td>4</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>long long<br> const long long &</td>
|
||||
<td>long long</td>
|
||||
<td>long</td>
|
||||
<td>8</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>unsigned long long<br>const unsigned long long &</td>
|
||||
<td>unsigned long long</td>
|
||||
<td>ulong</td>
|
||||
<td>8</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>float<br>const float &</td>
|
||||
<td>float</td>
|
||||
<td>float</td>
|
||||
<td>4</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>double<br> const double &</td>
|
||||
<td>double</td>
|
||||
<td>double</td>
|
||||
<td>8</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>size_t<br> const size_t &</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 &</td>
|
||||
<td>long long</td>
|
||||
<td>long</td>
|
||||
<td>8</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>unsigned long<br>const unsigned long &</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 & { const size_t & };
|
||||
</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 &</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 & { const size_t & };
|
||||
#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>
|
||||
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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() );
|
||||
|
|
|
@ -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() );
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
%}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;"
|
||||
|
|
|
@ -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]) }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue