[mapguide-commits] r9792 - in sandbox/jng/vanilla_swig/Bindings: . src/Bindings/SwigCommon/DotNet

svn_mapguide at osgeo.org svn_mapguide at osgeo.org
Thu Nov 19 02:52:30 PST 2020


Author: jng
Date: 2020-11-19 02:52:23 -0800 (Thu, 19 Nov 2020)
New Revision: 9792

Modified:
   sandbox/jng/vanilla_swig/Bindings/TODO.txt
   sandbox/jng/vanilla_swig/Bindings/src/Bindings/SwigCommon/DotNet/coreclr_compat.i
Log:
Change mg_exception_callback to take the class id instead of class name (as we no longer need that because of the flattened exception hierarchy). Use this class id to locate the MgException proxy class without needing another P/Invoke back across the native boundary to call GetClassId() for it. 

As a result, for thrown exceptions, we only wear the P/Invoke cost of the mg_exception_callback and whatever overhead for marshaling a pointer and an int instead of a pointer and a string and avoid a redundant GetClassId() P/Invoke when resolving the MgException proxy CLR type.

Modified: sandbox/jng/vanilla_swig/Bindings/TODO.txt
===================================================================
--- sandbox/jng/vanilla_swig/Bindings/TODO.txt	2020-11-19 10:14:38 UTC (rev 9791)
+++ sandbox/jng/vanilla_swig/Bindings/TODO.txt	2020-11-19 10:52:23 UTC (rev 9792)
@@ -10,7 +10,7 @@
  - Split .net binding into the Foundation/Geometry/PlatformBase/MapGuideCommon/Web layout (https://github.com/jumpinjackie/mapguide-api-bindings/issues/18)
    - [x] Add .targets files to each C# project so that native dlls are copied properly when consumed by legacy .net framework applications/libraries
    - [x] Consolidate TestCommon and TestMapGuideApi .net projects to unified netstandard2.0 libraries
-   - [ ] Tidy mg_exception_callback to no longer take an exception class name argument (it is no longer used or necessary)
+   - [x] Tidy mg_exception_callback to no longer take an exception class name argument (it is no longer used or necessary)
    - [ ] Add CentOS 6 Dockerfile that
       - Install SWIG and common libs tarball (from docker build system)
       - Install same compilers/tools as the same docker image used to produce the common libs tarball

Modified: sandbox/jng/vanilla_swig/Bindings/src/Bindings/SwigCommon/DotNet/coreclr_compat.i
===================================================================
--- sandbox/jng/vanilla_swig/Bindings/src/Bindings/SwigCommon/DotNet/coreclr_compat.i	2020-11-19 10:14:38 UTC (rev 9791)
+++ sandbox/jng/vanilla_swig/Bindings/src/Bindings/SwigCommon/DotNet/coreclr_compat.i	2020-11-19 10:52:23 UTC (rev 9792)
@@ -76,7 +76,7 @@
  */
 %insert(runtime) %{
 
-typedef void (SWIGSTDCALL* SWIG_CSharpMgExceptionCallback_t)(const void*, const char*); 
+typedef void (SWIGSTDCALL* SWIG_CSharpMgExceptionCallback_t)(const void*, const int); 
 
 static SWIG_CSharpMgExceptionCallback_t mg_exception_callback = NULL;
 
@@ -102,7 +102,7 @@
  */
 %pragma(csharp) imclasscode=%{
     protected class MgExceptionHelper {
-        public delegate void MgExceptionDelegate(global::System.IntPtr exPtr, string className);
+        public delegate void MgExceptionDelegate(global::System.IntPtr exPtr, int classId);
         
         static MgExceptionDelegate mgExceptionDelegate = new MgExceptionDelegate(SetPendingMgException);
         
@@ -109,7 +109,7 @@
         [global::System.Runtime.InteropServices.DllImport("$dllimport", EntryPoint="SWIGRegisterMgExceptionCallback_$module")]
         static extern void SWIGRegisterMgExceptionCallback_$module(MgExceptionDelegate mgDelegate);
         
-        static void SetPendingMgException(global::System.IntPtr exPtr, string className)
+        static void SetPendingMgException(global::System.IntPtr exPtr, int classId)
         {
             //IMPORTANT: It is imperative that nothing throws here as while such behavior is acceptable on Windows, in
             //CoreCLR on Linux such a throw is treated as a native throw and will crash the running application with SIGABRT
@@ -118,11 +118,11 @@
             //
             //SWIG by default will use SWIGPendingException to "stash" exceptions to be rethrown later on
             //we will use the same mechanism
-            global::System.Exception ex = $imclassname.MgObjectFactory.CreateObject<global::System.Exception>(exPtr);
+            global::System.Exception ex = $imclassname.MgObjectFactory.CreateObject<global::System.Exception>(exPtr, classId);
             if (ex != null)
                 SWIGPendingException.Set(ex);
             else //Shouldn't get here
-                SWIGPendingException.Set(new global::System.Exception("Attempted to construct a .net proxy of " + className + ", but instance is not an exception type"));
+                SWIGPendingException.Set(new global::System.Exception("Attempted to construct a .net proxy of what should be MgException but instance (id: " + classId + ") is not an exception type or failed to identify itself as one"));
         }
         
         static MgExceptionHelper()
@@ -204,11 +204,16 @@
             return str;
         }
     
-        internal static T CreateObject<T>(global::System.IntPtr objPtr) where T : class
+        internal static T CreateObject<T>(global::System.IntPtr objPtr, int? clsId = null) where T : class
         {
             T obj = null;
-            var clsId = $imclassname.GetClassId(objPtr);
-            var typeName = MgClassMap.GetTypeName(clsId);
+            //A class id may already be passed in when rethrowing .net exceptions, in which case: great!
+            //Otherwise call back to GetClassId for this value
+            if (clsId == null)
+            {
+                clsId = $imclassname.GetClassId(objPtr);
+            }
+            var typeName = MgClassMap.GetTypeName(clsId.Value);
             if (typeName == null) //Shouldn't happen. But if it did, this would mean we missed a spot when compiling class ids
             {
                 throw new global::System.Exception("Could not resolve .net type for this unmanaged pointer. The unmanaged pointer reported a class ID of: " + clsId);
@@ -286,8 +291,7 @@
     if (mgException != NULL) {
         //AddRef the exception as this is a Ptr<> it will auto-unref when leaving the method
         (*mgException).AddRef();
-        char* exClassName = mgException->GetMultiByteClassName();
-        mg_exception_callback(mgException.p, exClassName);
+        mg_exception_callback(mgException.p, mgException->GetClassId());
     }
 }
 



More information about the mapguide-commits mailing list