From 0383d08444eed8fa7e4476fe421c9ed14f92fba0 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Fri, 31 Jan 2014 22:47:12 +0000 Subject: [PATCH] Add new swigtype_inout.i library containing SWIGTYPE *& OUTPUT typemaps. --- CHANGES.current | 14 +++++ Examples/test-suite/common.mk | 1 + .../csharp/li_swigtype_inout_runme.cs | 56 +++++++++++++++++++ Examples/test-suite/li_swigtype_inout.i | 53 ++++++++++++++++++ Lib/csharp/swigtype_inout.i | 34 +++++++++++ 5 files changed, 158 insertions(+) create mode 100644 Examples/test-suite/csharp/li_swigtype_inout_runme.cs create mode 100644 Examples/test-suite/li_swigtype_inout.i create mode 100644 Lib/csharp/swigtype_inout.i diff --git a/CHANGES.current b/CHANGES.current index ca7503d41..c76a0c19f 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,20 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.0 (in progress) ============================ +2014-01-30: wsfulton + [C#] Add new swigtype_inout.i library containing SWIGTYPE *& OUTPUT typemaps. + + Example usage wrapping: + + void f(XXX *& x) { x = new XXX(111); } + + would be: + + XXX x = null; + f(out x); + // use x + x.Dispose(); // manually clear memory or otherwise leave out and leave it to the garbage collector + 2014-01-21: ianlancetaylor [Go] Add %go_import directive. diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index dc18852f7..5ce9a7031 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -251,6 +251,7 @@ CPP_TEST_CASES += \ li_cpointer \ li_std_auto_ptr \ li_stdint \ + li_swigtype_inout \ li_typemaps \ li_typemaps_apply \ li_windows \ diff --git a/Examples/test-suite/csharp/li_swigtype_inout_runme.cs b/Examples/test-suite/csharp/li_swigtype_inout_runme.cs new file mode 100644 index 000000000..0f9520d48 --- /dev/null +++ b/Examples/test-suite/csharp/li_swigtype_inout_runme.cs @@ -0,0 +1,56 @@ + +using System; +using li_swigtype_inoutNamespace; + +public class li_swigtype_inout_runme { + + public static void Main() { + XXX xxx = new XXX(999); + check_count(1); + XXX x1 = null; + XXX x2 = null; + XXX x3 = null; + XXX x4 = null; + li_swigtype_inout.ptr_ref_out(out x1, out x2, out x3, out x4); + check_value(111, x1.value); + check_value(222, x2.value); + check_value(333, x3.value); + check_value(444, x4.value); + check_count(5); + x1.Dispose(); + x2.Dispose(); + x3.Dispose(); + x4.Dispose(); + xxx.Dispose(); + check_count(0); + + x1 = null; + x2 = null; + x3 = null; + x4 = null; + new ConstructorTest(out x1, out x2, out x3, out x4); + check_count(4); + check_value(111, x1.value); + check_value(222, x2.value); + check_value(333, x3.value); + check_value(444, x4.value); + x1.Dispose(); + x2.Dispose(); + x3.Dispose(); + x4.Dispose(); + check_count(0); + } + + public static void check_count(int count) { + int actual = XXX.count; + if( count != actual ) { + throw new Exception(String.Format("Count wrong. Expected: {0} Got: {1}", count, actual)); + } + } + + public static void check_value(int expected, int actual) { + if( expected != actual ) { + throw new Exception(String.Format("Wrong value. Expected: {0} Got: {1}", expected, actual)); + } + } +} diff --git a/Examples/test-suite/li_swigtype_inout.i b/Examples/test-suite/li_swigtype_inout.i new file mode 100644 index 000000000..8b695a925 --- /dev/null +++ b/Examples/test-suite/li_swigtype_inout.i @@ -0,0 +1,53 @@ +%module li_swigtype_inout + +// Test SWIGTYPE *& typemaps in swigtype_inout.i library + +#ifdef SWIGCSHARP +%include +%apply SWIGTYPE *& OUTPUT { SWIGTYPE *& } +#endif + +%ignore XXX::operator=; + +%inline %{ +#include +struct XXX { + XXX(int value) : value(value) { + if (debug) std::cout << "Default Constructor " << value << " " << this << std::endl; + count++; + } + XXX(const XXX &other) { + value = other.value; + if (debug) std::cout << "Copy Constructor " << value << " " << this << std::endl; + count++; + } + XXX& operator=(const XXX &other) { + value = other.value; + if (debug) std::cout << "Assignment operator " << value << " " << this << std::endl; + return *this; + } + ~XXX() { + if (debug) std::cout << "Destructor " << value << " " << this << std::endl; + count--; + } + void showInfo() { + if (debug) std::cout << "Info " << value << " " << this << std::endl; + } + int value; + static const bool debug = false; + static int count; +}; +int XXX::count = 0; + +void ptr_ref_out(XXX *& x1, XXX *& x2, XXX const*& x3, XXX const*& x4) { + x1 = new XXX(111); + x2 = new XXX(222); + x3 = new XXX(333); + x4 = new XXX(444); +} +struct ConstructorTest { + ConstructorTest(XXX *& x1, XXX *& x2, XXX const*& x3, XXX const*& x4) { + ptr_ref_out(x1, x2, x3, x4); + } +}; +%} diff --git a/Lib/csharp/swigtype_inout.i b/Lib/csharp/swigtype_inout.i new file mode 100644 index 000000000..e7312e8fe --- /dev/null +++ b/Lib/csharp/swigtype_inout.i @@ -0,0 +1,34 @@ +/* ----------------------------------------------------------------------------- + * swigtype_inout.i + * + * Pointer pointer and pointer reference handling typemap library for non-primitive types + * + * These mappings provide support for input/output arguments and common + * uses for C/C++ pointer references and pointer to pointers. + * + * These are named typemaps (OUTPUT) and can be used like any named typemap. + * Alternatively they can be made the default by using %apply: + * %apply SWIGTYPE *& OUTPUT { SWIGTYPE *& } + * ----------------------------------------------------------------------------- */ + +/* + * OUTPUT typemaps. Example usage wrapping: + * + * void f(XXX *& x) { x = new XXX(111); } + * + * would be: + * + * XXX x = null; + * f(out x); + * // use x + * x.Dispose(); // manually clear memory or otherwise leave out and leave it to the garbage collector + */ +%typemap(ctype) SWIGTYPE *& OUTPUT "void **" +%typemap(imtype, out="global::System.IntPtr") SWIGTYPE *& OUTPUT "out global::System.IntPtr" +%typemap(cstype) SWIGTYPE *& OUTPUT "out $*csclassname" +%typemap(csin, + pre=" global::System.IntPtr cPtr_$csinput = global::System.IntPtr.Zero;", + post=" $csinput = (cPtr_$csinput == global::System.IntPtr.Zero) ? null : new $*csclassname(cPtr_$csinput, true);", + cshin="out $csinput") SWIGTYPE *& OUTPUT "out cPtr_$csinput" +%typemap(in) SWIGTYPE *& OUTPUT %{ $1 = ($1_ltype)$input; %} +%typemap(freearg) SWIGTYPE *& OUTPUT ""