diff --git a/Examples/test-suite/exception_order.i b/Examples/test-suite/exception_order.i index 07815be2b..20f0c6331 100644 --- a/Examples/test-suite/exception_order.i +++ b/Examples/test-suite/exception_order.i @@ -2,11 +2,6 @@ %include "exception.i" -#ifdef SWIGCSHARP -#undef %exception -#define %exception %csexception -#endif - /* last resource, catch everything but don't override user's throw declarations. diff --git a/Lib/csharp/csharp.swg b/Lib/csharp/csharp.swg index f87809609..8895e7485 100644 --- a/Lib/csharp/csharp.swg +++ b/Lib/csharp/csharp.swg @@ -167,10 +167,11 @@ $1 = &temp; %} /* Default handling. Object passed by value. Convert to a pointer */ %typemap(in, canthrow=1) SWIGTYPE ($&1_type argp) %{ argp = ($&1_ltype)$input; - if (!argp) { - SWIG_CSharpThrowException(SWIG_CSharpNullReferenceException, "Attempt to dereference null $1_type"); - } - $1 = *argp; %} + if (!argp) { + SWIG_CSharpSetPendingException(SWIG_CSharpNullReferenceException, "Attempt to dereference null $1_type"); + return $null; + } + $1 = *argp; %} %typemap(out) SWIGTYPE #ifdef __cplusplus %{$result = new $1_ltype(($1_ltype &)$1); %} @@ -187,7 +188,8 @@ $1 = &temp; %} %typemap(in) SWIGTYPE (CLASS::*) %{ $1 = *($&1_ltype)&$input; %} %typemap(in, canthrow=1) SWIGTYPE & %{ $1 = ($1_ltype)$input; if(!$1) { - SWIG_CSharpThrowException(SWIG_CSharpNullReferenceException, "$1_type reference is null"); + SWIG_CSharpSetPendingException(SWIG_CSharpNullReferenceException, "$1_type reference is null"); + return $null; } %} %typemap(out) SWIGTYPE *, SWIGTYPE & %{ $result = (void *)$1; %} %typemap(out) SWIGTYPE (CLASS::*) %{ *($&1_ltype)&$result = $1; %} @@ -293,16 +295,19 @@ $1 = &temp; %} unsigned short { char error_msg[256]; sprintf(error_msg, "C++ $1_type exception thrown, value: %d", $1); - SWIG_CSharpThrowException(SWIG_CSharpException, error_msg); + SWIG_CSharpSetPendingException(SWIG_CSharpSystemException, error_msg); + return $null; } %typemap(throws, canthrow=1) SWIGTYPE, SWIGTYPE &, SWIGTYPE *, SWIGTYPE [ANY] %{ (void)$1; - SWIG_CSharpThrowException(SWIG_CSharpException, "C++ $1_type exception thrown"); + SWIG_CSharpSetPendingException(SWIG_CSharpSystemException, "C++ $1_type exception thrown"); + return $null; %} %typemap(throws, canthrow=1) char * %{ - SWIG_CSharpThrowException(SWIG_CSharpException, $1); + SWIG_CSharpSetPendingException(SWIG_CSharpSystemException, $1); + return $null; %} @@ -332,10 +337,10 @@ $1 = &temp; %} /* The csout typemap is used for converting function return types from the return type * used in the PInvoke class to the type returned by the proxy, module or type wrapper class. * The $excode special variable is replaced by the excode typemap attribute code if the - * method can throw any exceptions, otherwise replaced by nothing. */ + * method can throw any exceptions from unmanaged code, otherwise replaced by nothing. */ // Macro used by the $excode special variable -%define SWIGEXCODE "\n if ($modulePINVOKE.ExceptionPending) throw $modulePINVOKE.RetrievePendingException();" %enddef +%define SWIGEXCODE "\n if ($modulePINVOKE.SWIGPendingException.Pending) throw $modulePINVOKE.SWIGPendingException.Retrieve();" %enddef %typemap(csout, excode=SWIGEXCODE) bool, const bool & { bool ret = $imcall;$excode @@ -489,11 +494,6 @@ $1 = &temp; %} swigCPtr = cPtr; } - protected virtual void swigSetup(IntPtr cPtr, bool cMemoryOwn) { - swigCMemOwn = cMemoryOwn; - swigCPtr = cPtr; - } - internal static IntPtr getCPtr($csclassname obj) { return (obj == null) ? IntPtr.Zero : obj.swigCPtr; } @@ -503,12 +503,7 @@ $1 = &temp; %} %typemap(csbody_derived) SWIGTYPE %{ private IntPtr swigCPtr; - internal $csclassname(IntPtr cPtr, bool cMemoryOwn) : base((cPtr == IntPtr.Zero) ? cPtr : $modulePINVOKE.$csclassnameUpcast(cPtr), cMemoryOwn) { - swigCPtr = cPtr; - } - - protected override void swigSetup(IntPtr cPtr, bool cMemoryOwn) { - base.swigSetup($modulePINVOKE.$csclassnameUpcast(cPtr), cMemoryOwn); + internal $csclassname(IntPtr cPtr, bool cMemoryOwn) : base($modulePINVOKE.$csclassnameUpcast(cPtr), cMemoryOwn) { swigCPtr = cPtr; } @@ -540,8 +535,7 @@ $1 = &temp; %} } %} -%typemap(csconstruct, excode=SWIGEXCODE) SWIGTYPE %{: this(IntPtr.Zero, false) { - swigSetup($imcall, true);$excode +%typemap(csconstruct, excode=SWIGEXCODE) SWIGTYPE %{: this($imcall, true) {$excode } %} @@ -570,8 +564,7 @@ $1 = &temp; %} #define %csconstvalue(value) %feature("cs:constvalue",value) #define %csenum(wrapapproach) %feature("cs:enum","wrapapproach") #define %csmethodmodifiers %feature("cs:methodmodifiers") -#define %csexception %feature("except",canthrow=1) -#define %nocsexception %feature("except","") +#define %csnothrowexception %feature("except") %pragma(csharp) imclassclassmodifiers="class" %pragma(csharp) moduleclassmodifiers="public class" diff --git a/Lib/csharp/csharphead.swg b/Lib/csharp/csharphead.swg index ccbf5263d..8302b4959 100644 --- a/Lib/csharp/csharphead.swg +++ b/Lib/csharp/csharphead.swg @@ -20,7 +20,7 @@ %insert(runtime) %{ /* Support for throwing C# exceptions from C/C++ */ typedef enum { - SWIG_CSharpException, + SWIG_CSharpSystemException, SWIG_CSharpOutOfMemoryException, SWIG_CSharpIndexOutOfRangeException, SWIG_CSharpDivideByZeroException, @@ -36,15 +36,15 @@ typedef struct { } SWIG_CSharpExceptions_t; static SWIG_CSharpExceptions_t SWIG_csharp_exceptions[] = { - { SWIG_CSharpException, NULL }, + { SWIG_CSharpSystemException, NULL }, { SWIG_CSharpOutOfMemoryException, NULL }, { SWIG_CSharpIndexOutOfRangeException, NULL }, { SWIG_CSharpDivideByZeroException, NULL }, { SWIG_CSharpArgumentOutOfRangeException, NULL }, { SWIG_CSharpNullReferenceException, NULL } }; -static void SWIG_CSharpThrowException(SWIG_CSharpExceptionCodes code, const char *msg) { - SWIG_CSharpExceptionCallback_t callback = SWIG_csharp_exceptions[SWIG_CSharpException].callback; +static void SWIG_CSharpSetPendingException(SWIG_CSharpExceptionCodes code, const char *msg) { + SWIG_CSharpExceptionCallback_t callback = SWIG_csharp_exceptions[SWIG_CSharpSystemException].callback; if (code >=0 && (size_t)code < sizeof(SWIG_csharp_exceptions)/sizeof(SWIG_CSharpExceptions_t)) { callback = SWIG_csharp_exceptions[code].callback; } @@ -62,7 +62,7 @@ DllExport void SWIGSTDCALL SWIGRegisterExceptionCallbacks_$module(SWIG_CSharpExc SWIG_CSharpExceptionCallback_t divideByZero, SWIG_CSharpExceptionCallback_t argumentOutOfRange, SWIG_CSharpExceptionCallback_t nullReference) { - SWIG_csharp_exceptions[SWIG_CSharpException].callback = systemException; + SWIG_csharp_exceptions[SWIG_CSharpSystemException].callback = systemException; SWIG_csharp_exceptions[SWIG_CSharpOutOfMemoryException].callback = outOfMemory; SWIG_csharp_exceptions[SWIG_CSharpIndexOutOfRangeException].callback = indexOutOfRange; SWIG_csharp_exceptions[SWIG_CSharpDivideByZeroException].callback = divideByZero; @@ -74,46 +74,46 @@ DllExport void SWIGSTDCALL SWIGRegisterExceptionCallbacks_$module(SWIG_CSharpExc %pragma(csharp) imclasscode=%{ class SWIGExceptionHelper { - public delegate void SWIGExceptionDelegate(string message); + public delegate void ExceptionDelegate(string message); - static SWIGExceptionDelegate systemDelegate = new SWIGExceptionDelegate(ThrowSystemException); - static SWIGExceptionDelegate outOfMemoryDelegate = new SWIGExceptionDelegate(ThrowOutOfMemoryException); - static SWIGExceptionDelegate indexOutOfRangeDelegate = new SWIGExceptionDelegate(ThrowIndexOutOfRangeException); - static SWIGExceptionDelegate divideByZeroDelegate = new SWIGExceptionDelegate(ThrowDivideByZeroException); - static SWIGExceptionDelegate argumentOutOfRangeDelegate = new SWIGExceptionDelegate(ThrowArgumentOutOfRangeException); - static SWIGExceptionDelegate nullReferenceDelegate = new SWIGExceptionDelegate(ThrowNullReferenceException); + static ExceptionDelegate systemDelegate = new ExceptionDelegate(ThrowSystemException); + static ExceptionDelegate outOfMemoryDelegate = new ExceptionDelegate(ThrowOutOfMemoryException); + static ExceptionDelegate indexOutOfRangeDelegate = new ExceptionDelegate(ThrowIndexOutOfRangeException); + static ExceptionDelegate divideByZeroDelegate = new ExceptionDelegate(ThrowDivideByZeroException); + static ExceptionDelegate argumentOutOfRangeDelegate = new ExceptionDelegate(ThrowArgumentOutOfRangeException); + static ExceptionDelegate nullReferenceDelegate = new ExceptionDelegate(ThrowNullReferenceException); [DllImport("$dllimport", EntryPoint="SWIGRegisterExceptionCallbacks_$module")] public static extern void SWIGRegisterExceptionCallbacks_$module( - SWIGExceptionDelegate systemExceptionDelegate, - SWIGExceptionDelegate outOfMemoryDelegate, - SWIGExceptionDelegate indexOutOfRangeDelegate, - SWIGExceptionDelegate divideByZeroDelegate, - SWIGExceptionDelegate argumentOutOfRangeDelegate, - SWIGExceptionDelegate nullReferenceDelegate); + ExceptionDelegate systemExceptionDelegate, + ExceptionDelegate outOfMemoryDelegate, + ExceptionDelegate indexOutOfRangeDelegate, + ExceptionDelegate divideByZeroDelegate, + ExceptionDelegate argumentOutOfRangeDelegate, + ExceptionDelegate nullReferenceDelegate); static void ThrowSystemException(string message) { - throw new System.SystemException(message); + SWIGPendingException.Set(new System.SystemException(message)); } static void ThrowOutOfMemoryException(string message) { - throw new System.OutOfMemoryException(message); + SWIGPendingException.Set(new System.OutOfMemoryException(message)); } static void ThrowIndexOutOfRangeException(string message) { - throw new System.IndexOutOfRangeException(message); + SWIGPendingException.Set(new System.IndexOutOfRangeException(message)); } static void ThrowDivideByZeroException(string message) { - throw new System.DivideByZeroException(message); + SWIGPendingException.Set(new System.DivideByZeroException(message)); } static void ThrowArgumentOutOfRangeException(string message) { - throw new System.ArgumentOutOfRangeException(message); + SWIGPendingException.Set(new System.ArgumentOutOfRangeException(message)); } static void ThrowNullReferenceException(string message) { - throw new System.NullReferenceException(message); + SWIGPendingException.Set(new System.NullReferenceException(message)); } static SWIGExceptionHelper() { @@ -121,41 +121,45 @@ DllExport void SWIGSTDCALL SWIGRegisterExceptionCallbacks_$module(SWIG_CSharpExc } } - static SWIGExceptionHelper exceptionHelper = new SWIGExceptionHelper(); + static SWIGExceptionHelper swigExceptionHelper = new SWIGExceptionHelper(); - [ThreadStatic] - private static Exception pendingException = null; - private static int numExceptionsPending = 0; + public class SWIGPendingException { + [ThreadStatic] + private static Exception pendingException = null; + private static int numExceptionsPending = 0; - public static bool ExceptionPending { - get { - bool pending = false; - if (numExceptionsPending > 0) - if (pendingException != null) - pending = true; - return pending; - } - } - - public static void SetPendingException(Exception e) { - pendingException = e; - lock(typeof($modulePINVOKE)) { - numExceptionsPending++; + public static bool Pending { + get { + bool pending = false; + if (numExceptionsPending > 0) + if (pendingException != null) + pending = true; + return pending; + } } - } - public static Exception RetrievePendingException() { - Exception e = null; - if (numExceptionsPending > 0) { - if (pendingException != null) { - e = pendingException; - pendingException = null; - lock(typeof($modulePINVOKE)) { - numExceptionsPending--; - } + public static void Set(Exception e) { + if (pendingException != null) + throw new Exception("Throwing exceptions from unmanaged code has gone broken down"); + pendingException = e; + lock(typeof($modulePINVOKE)) { + numExceptionsPending++; } } - return e; + + public static Exception Retrieve() { + Exception e = null; + if (numExceptionsPending > 0) { + if (pendingException != null) { + e = pendingException; + pendingException = null; + lock(typeof($modulePINVOKE)) { + numExceptionsPending--; + } + } + } + return e; + } } %} @@ -183,7 +187,7 @@ static SWIG_CSharpStringHelperCallback SWIG_csharp_string_callback = NULL; } } - static SWIGStringHelper stringHelper = new SWIGStringHelper(); + static SWIGStringHelper swigStringHelper = new SWIGStringHelper(); %} %insert(runtime) %{ @@ -196,5 +200,5 @@ DllExport void SWIGSTDCALL SWIGRegisterStringCallback_$module(SWIG_CSharpStringH /* Contract support */ -#define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_CSharpThrowException(SWIG_CSharpArgumentOutOfRangeException, msg); return nullreturn; } else +#define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_CSharpSetPendingException(SWIG_CSharpArgumentOutOfRangeException, msg); return nullreturn; } else %} diff --git a/Lib/csharp/enums.swg b/Lib/csharp/enums.swg index 03acb7ea4..f75e6fec1 100644 --- a/Lib/csharp/enums.swg +++ b/Lib/csharp/enums.swg @@ -17,7 +17,8 @@ %typemap(throws, canthrow=1) const enum SWIGTYPE & %{ (void)$1; - SWIG_CSharpThrowException(SWIG_CSharpException, "C++ $1_type exception thrown"); + SWIG_CSharpSetPendingException(SWIG_CSharpSystemException, "C++ $1_type exception thrown"); + return $null; %} %typemap(csin) const enum SWIGTYPE & "(int)$csinput" @@ -44,7 +45,8 @@ %typemap(throws, canthrow=1) enum SWIGTYPE %{ (void)$1; - SWIG_CSharpThrowException(SWIG_CSharpException, "C++ $1_type exception thrown"); + SWIG_CSharpSetPendingException(SWIG_CSharpSystemException, "C++ $1_type exception thrown"); + return $null; %} %typemap(csin) enum SWIGTYPE "(int)$csinput" diff --git a/Lib/csharp/enumsimple.swg b/Lib/csharp/enumsimple.swg index 9a4cf7a1e..b33962995 100644 --- a/Lib/csharp/enumsimple.swg +++ b/Lib/csharp/enumsimple.swg @@ -19,7 +19,8 @@ %typemap(throws, canthrow=1) const enum SWIGTYPE & %{ (void)$1; - SWIG_CSharpThrowException(SWIG_CSharpException, "C++ $1_type exception thrown"); + SWIG_CSharpSetPendingException(SWIG_CSharpSystemException, "C++ $1_type exception thrown"); + return $null; %} %typemap(csin) const enum SWIGTYPE & "$csinput" @@ -46,7 +47,8 @@ %typemap(throws, canthrow=1) enum SWIGTYPE %{ (void)$1; - SWIG_CSharpThrowException(SWIG_CSharpException, "C++ $1_type exception thrown"); + SWIG_CSharpSetPendingException(SWIG_CSharpSystemException, "C++ $1_type exception thrown"); + return $null; %} %typemap(csin) enum SWIGTYPE "$csinput" diff --git a/Lib/csharp/enumtypesafe.swg b/Lib/csharp/enumtypesafe.swg index 6e152b6f3..cdf22a923 100644 --- a/Lib/csharp/enumtypesafe.swg +++ b/Lib/csharp/enumtypesafe.swg @@ -18,7 +18,8 @@ %typemap(throws, canthrow=1) const enum SWIGTYPE & %{ (void)$1; - SWIG_CSharpThrowException(SWIG_CSharpException, "C++ $1_type exception thrown"); + SWIG_CSharpSetPendingException(SWIG_CSharpSystemException, "C++ $1_type exception thrown"); + return $null; %} %typemap(csin) const enum SWIGTYPE & "$csinput.swigValue" @@ -45,7 +46,8 @@ %typemap(throws, canthrow=1) enum SWIGTYPE %{ (void)$1; - SWIG_CSharpThrowException(SWIG_CSharpException, "C++ $1_type exception thrown"); + SWIG_CSharpSetPendingException(SWIG_CSharpSystemException, "C++ $1_type exception thrown"); + return $null; %} %typemap(csin) enum SWIGTYPE "$csinput.swigValue" diff --git a/Lib/csharp/std_string.i b/Lib/csharp/std_string.i index e4cb26e0a..6c650aa83 100644 --- a/Lib/csharp/std_string.i +++ b/Lib/csharp/std_string.i @@ -27,7 +27,10 @@ class string; %typemap(cstype) string "string" %typemap(in, canthrow=1) string -%{ if (!$input) SWIG_CSharpThrowException(SWIG_CSharpNullReferenceException, "null string"); +%{ if (!$input) { + SWIG_CSharpSetPendingException(SWIG_CSharpNullReferenceException, "null string"); + return $null; + } $1 = std::string($input); %} %typemap(out) string %{ $result = SWIG_csharp_string_callback($1.c_str()); %} @@ -49,7 +52,8 @@ class string; %typemap(typecheck) string = char *; %typemap(throws, canthrow=1) string %{ - SWIG_CSharpThrowException(SWIG_CSharpException, $1.c_str()); + SWIG_CSharpSetPendingException(SWIG_CSharpSystemException, $1.c_str()); + return $null; %} // const string & @@ -58,7 +62,10 @@ class string; %typemap(cstype) const string & "string" %typemap(in, canthrow=1) const string & -%{ if (!$input) SWIG_CSharpThrowException(SWIG_CSharpNullReferenceException, "null string"); +%{ if (!$input) { + SWIG_CSharpSetPendingException(SWIG_CSharpNullReferenceException, "null string"); + return $null; + } std::string $1_str($input); $1 = &$1_str; %} %typemap(out) const string & %{ $result = SWIG_csharp_string_callback($1->c_str()); %} @@ -81,7 +88,8 @@ class string; %typemap(typecheck) const string & = char *; %typemap(throws, canthrow=1) const string & %{ - SWIG_CSharpThrowException(SWIG_CSharpException, $1.c_str()); + SWIG_CSharpSetPendingException(SWIG_CSharpSystemException, $1.c_str()); + return $null; %} } diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index 23a4edf41..42898c56f 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -758,9 +758,9 @@ class CSHARP : public Language { if(Strstr(f->code, "SWIG_exception")) { Swig_warning(WARN_CSHARP_CANTHROW, input_file, line_number, "Unmanaged code contains a call to SWIG_exception and C# code does not handle pending exceptions via the canthrow attribute.\n"); - } else if(Strstr(f->code, "SWIG_CSharpThrowException")) { + } else if(Strstr(f->code, "SWIG_CSharpSetPendingException")) { Swig_warning(WARN_CSHARP_CANTHROW, input_file, line_number, - "Unmanaged code contains a call to SWIG_CSharpThrowException and C# code does not handle pending exceptions via the canthrow attribute.\n"); + "Unmanaged code contains a call to SWIG_CSharpSetPendingException and C# code does not handle pending exceptions via the canthrow attribute.\n"); } } }