Author Topic: PlatformUtils.vb (for dealing with IntersectWith issues)  (Read 3256 times)

0 Members and 1 Guest are viewing this topic.

TheMaster

  • Guest
PlatformUtils.vb (for dealing with IntersectWith issues)
« on: April 12, 2013, 11:11:51 AM »
Posted here because you can't post source code files on Autodesk's brain-dead discussion forum :roll:

Code - Visual Basic: [Select]
  1. ' PlatformUtils.vb  copyright(c) 2009   Tony Tanzillo
  2. '
  3. '
  4. ' Abstract:
  5. '
  6. '   Platform compatibiity helper methods that allow an
  7. '   assembly to run on both 32 and 64 bit systems.
  8. '
  9. '   Refer to PlatformUtils.cs for more complete documentation.
  10. '
  11.  
  12. Imports System.Runtime.CompilerServices
  13. Imports Autodesk.AutoCAD.DatabaseServices
  14. Imports Autodesk.AutoCAD.Geometry
  15. Imports System.Reflection
  16.  
  17. <Extension()> _
  18. Public Module PlatformCompatibilityExtensionMethods
  19.  
  20.    Sub New()
  21.       Dim types1 As Type() = Nothing
  22.       Dim types2 As Type() = Nothing
  23.       If (IntPtr.Size > 4) Then
  24.          types1 = New Type() {GetType(Entity), GetType(Intersect), GetType(Point3dCollection), GetType(Long), GetType(Long)}
  25.          types2 = New Type() {GetType(Entity), GetType(Intersect), GetType(Plane), GetType(Point3dCollection), GetType(Long), GetType(Long)}
  26.       Else
  27.          types1 = New Type() {GetType(Entity), GetType(Intersect), GetType(Point3dCollection), GetType(Integer), GetType(Integer)}
  28.          types2 = New Type() {GetType(Entity), GetType(Intersect), GetType(Plane), GetType(Point3dCollection), GetType(Integer), GetType(Integer)}
  29.       End If
  30.       PlatformCompatibilityExtensionMethods.intersectWithMethod1 = GetType(Entity).GetMethod("IntersectWith", (BindingFlags.Public Or BindingFlags.Instance), Nothing, types1, Nothing)
  31.       PlatformCompatibilityExtensionMethods.intersectWithMethod2 = GetType(Entity).GetMethod("IntersectWith", (BindingFlags.Public Or BindingFlags.Instance), Nothing, types2, Nothing)
  32.    End Sub
  33.  
  34.    <Extension()> _
  35.    Public Function IntersectWith(ByVal entity As Entity, ByVal other As Entity, ByVal intersectType As Intersect, ByVal points As Point3dCollection) As Integer
  36.       Dim start As Integer = points.Count
  37.       Dim args As Object() = Nothing
  38.       If (IntPtr.Size > 4) Then
  39.          args = New Object() {other, intersectType, points, CLng(0), CLng(0)}
  40.       Else
  41.          args = New Object() {other, intersectType, points, CInt(0), CInt(0)}
  42.       End If
  43.       PlatformCompatibilityExtensionMethods.intersectWithMethod1.Invoke(Nothing, _
  44.          (BindingFlags.NonPublic Or BindingFlags.Static), Nothing, args, Nothing)
  45.       Return (points.Count - start)
  46.    End Function
  47.  
  48.    <Extension()> _
  49.    Public Function IntersectWith(ByVal entity As Entity, ByVal other As Entity, ByVal intersectType As Intersect, ByVal plane As Plane, ByVal points As Point3dCollection) As Integer
  50.       Dim start As Integer = points.Count
  51.       Dim args As Object() = Nothing
  52.       If (IntPtr.Size > 4) Then
  53.          args = New Object() {other, intersectType, plane, points, CLng(0), CLng(0)}
  54.       Else
  55.          args = New Object() {other, intersectType, plane, points, CInt(0), CInt(0)}
  56.       End If
  57.       PlatformCompatibilityExtensionMethods.intersectWithMethod2.Invoke(Nothing, _
  58.          (BindingFlags.NonPublic Or BindingFlags.Static), Nothing, args, Nothing)
  59.       Return (points.Count - start)
  60.    End Function
  61.  
  62.    <Extension()> _
  63.    Public Function IntersectWith(ByVal entity As Entity, ByVal other As Entity, ByVal intersectType As Intersect, ByVal points As Point3dCollection, ByVal thisGsMarker As IntPtr, ByVal otherGsMarker As IntPtr) As Integer
  64.       Dim start As Integer = points.Count
  65.       Dim args As Object() = Nothing
  66.       If (IntPtr.Size > 4) Then
  67.          args = New Object() {other, intersectType, points, thisGsMarker.ToInt64, otherGsMarker.ToInt64}
  68.       Else
  69.          args = New Object() {other, intersectType, points, thisGsMarker.ToInt32, otherGsMarker.ToInt32}
  70.       End If
  71.       PlatformCompatibilityExtensionMethods.intersectWithMethod1.Invoke(Nothing, _
  72.          (BindingFlags.NonPublic Or BindingFlags.Static), Nothing, args, Nothing)
  73.       Return (points.Count - start)
  74.    End Function
  75.  
  76.    <Extension()> _
  77.    Public Function IntersectWith(ByVal entity As Entity, ByVal other As Entity, ByVal intersectType As Intersect, ByVal plane As Plane, ByVal points As Point3dCollection, ByVal thisGsMarker As IntPtr, ByVal otherGsMarker As IntPtr) As Integer
  78.       Dim start As Integer = points.Count
  79.       Dim args As Object() = Nothing
  80.       If (IntPtr.Size > 4) Then
  81.          args = New Object() {other, intersectType, plane, points, thisGsMarker.ToInt64, otherGsMarker.ToInt64}
  82.       Else
  83.          args = New Object() {other, intersectType, plane, points, thisGsMarker.ToInt32, otherGsMarker.ToInt32}
  84.       End If
  85.       PlatformCompatibilityExtensionMethods.intersectWithMethod2.Invoke(Nothing, _
  86.          (BindingFlags.NonPublic Or BindingFlags.Static), Nothing, args, Nothing)
  87.       Return (points.Count - start)
  88.    End Function
  89.  
  90.    Private intersectWithMethod1 As MethodInfo = Nothing
  91.    Private intersectWithMethod2 As MethodInfo = Nothing
  92.  
  93. End Module
  94.  
  95.  
« Last Edit: April 16, 2013, 01:25:33 PM by TT »

csharpbird

  • Newt
  • Posts: 64
Re: PlatformUtils.vb (for dealing with IntersectWith issues)
« Reply #1 on: April 12, 2013, 11:48:44 PM »
hi,Tony
Can you provide PlatformUtils.cs?

TheMaster

  • Guest
Re: PlatformUtils.vb (for dealing with IntersectWith issues)
« Reply #2 on: April 13, 2013, 08:36:40 AM »
If I recall correctly, this isn't required in versions after AutoCAD 2009,
and doesn't work in later releases, because they fixed the bug, and in
the process, changed the signatures again.

Code - C#: [Select]
  1.  
  2. /// PlatformUtils.cs  copyright(c) 2009  Tony Tanzillo
  3. ///
  4. /// AutoCAD .NET Programming Samples: PlatformUtils
  5. ///
  6. /// Abstract:
  7. ///
  8. ///   Platform compatibiity helper methods that allow an
  9. ///   assembly to run on both 32 and 64 bit systems.
  10. ///
  11. ///
  12. /// The Problem:
  13. ///
  14. ///    There are a number of bugs in AutoCAD's managed runtime
  15. ///    that manifest in the form of differing method signatures
  16. ///    in the managed runtime libraries included with the 32 and
  17. ///    64 bit product releases.
  18. ///    
  19. ///    One such case involves the Entity's IntersectWith() method,
  20. ///    which has different signatures on 32 and 64 bit platforms,
  21. ///    requiring different, platform-specific calling code.
  22. ///
  23. ///    On 32 bit AutoCAD, the last two arguments to IntersectWith()
  24. ///    are typed as Int32. On 64 bit AutoCAD, those same arguments
  25. ///    are typed as Int64. By default, code compiled with the 32 bit
  26. ///    versions of AutoCAD's managed runtime will fail on 64 bit
  27. ///    AutoCAD, because the method with the required signature can't
  28. ///    be found.
  29. ///    
  30. /// The Workaround:
  31. ///    
  32. ///    The code provided herein serves as a workaround for this bug,
  33. ///    that allows a single, platform-neutral managed assembly to
  34. ///    run on both 32 and 64 bit AutoCAD without error.
  35. ///
  36.  
  37. using System;
  38. using System.Collections.Generic;
  39. using System.Linq;
  40. using System.Text;
  41. using Autodesk.AutoCAD.Geometry;
  42. using System.Reflection;
  43.  
  44. namespace Autodesk.AutoCAD.DatabaseServices
  45. {
  46.  
  47.    /// <summary>
  48.    ///
  49.    /// Platform compatibility extension methods for
  50.    /// Autodesk.AutoCAD.DatabaseServices.Entity
  51.    ///
  52.    /// These methods make it easier to deploy a single,
  53.    /// platform-neutral managed assembly that can run
  54.    /// on both 32 and 64 bit AutoCAD.
  55.    ///
  56.    /// </summary>
  57.  
  58.    public static class PlatformCompatibilityExtensionMethods
  59.    {
  60.  
  61.       /// <summary>
  62.       /// Extension methods that act as platform-independent
  63.       /// surrogates for the Entity.IntersectWith() method,
  64.       /// allowing a single managed assembly that uses them
  65.       /// to run on both 32 or 64 bit AutoCAD.
  66.       ///
  67.       /// The following extension method overloads are supported:
  68.       ///
  69.       ///   IntersectWith( Entity, Intersect, Point3dCollection );
  70.       ///   IntersectWith( Entity, Intersect, Point3dCollection, IntPtr, IntPtr );
  71.       ///   IntersectWith( Entity, Intersect, Plane, Point3dCollection );
  72.       ///   IntersectWith( Entity, Intersect, Plane, Point3dCollection, IntPtr, IntPtr );
  73.       ///    
  74.       /// The versions which do not require IntPtr as the last two arguments
  75.       /// pass the default of 0 for the GsMarker parameters of the Entity's
  76.       /// IntersectWith() method.
  77.       ///
  78.       /// The versions that require two IntPtr arguments as their last two
  79.       /// parameters convert the passed IntPtr to the required type (Int32
  80.       /// or Int64, depending on the platform the code is running on), and
  81.       /// pass those values for the GsMarker parameters.
  82.       ///
  83.       /// All other parameters are equivalent to the corresponding
  84.       /// parameters of the Entity's IntersectWith() method.
  85.       ///
  86.       /// All overloads return the number of intersections found.
  87.       ///
  88.       /// Use these methods in lieu of Entity.IntersectWith() to
  89.       /// enable your code to run on both 32 and 64 bit systems.
  90.       ///
  91.       /// Performance Issues:
  92.       ///
  93.       /// Because these extension methods use reflection to invoke the
  94.       /// underlying methods they act as surrogates for, they will not
  95.       /// perform as well as direct calls to those underlying methods.
  96.       /// This can be an issue in performance intensive applications,
  97.       /// and in such cases a hand-coded solution that avoids the use
  98.       /// of reflection may be a preferable alternative.
  99.       ///
  100.       /// </summary>
  101.  
  102.  
  103.       static PlatformCompatibilityExtensionMethods()
  104.       {
  105.          Object test32 = (Int32) 0;
  106.          Object test64 = (Int64) 0;
  107.  
  108.          Console.Write( test32 );
  109.          Console.Write( test64 );
  110.  
  111.          Type[] types1 = null;
  112.          Type[] types2 = null;
  113.          if( IntPtr.Size > 4 )
  114.          {
  115.             types1 = new Type[] { typeof( Entity ), typeof( Intersect ), typeof( Point3dCollection ), typeof( Int64 ), typeof( Int64 ) };
  116.             types2 = new Type[] { typeof( Entity ), typeof( Intersect ), typeof( Plane ), typeof( Point3dCollection ), typeof( Int64 ), typeof( Int64 ) };
  117.          }
  118.          else
  119.          {
  120.             types1 = new Type[] { typeof( Entity ), typeof( Intersect ), typeof( Point3dCollection ), typeof( Int32 ), typeof( Int32 ) };
  121.             types2 = new Type[] { typeof( Entity ), typeof( Intersect ), typeof( Plane ), typeof( Point3dCollection ), typeof( Int32 ), typeof( Int32 ) };
  122.          }
  123.  
  124.          intersectWithMethod1 = typeof( Entity ).GetMethod( "IntersectWith", BindingFlags.Public | BindingFlags.Instance, null, types1, null );
  125.          intersectWithMethod2 = typeof( Entity ).GetMethod( "IntersectWith", BindingFlags.Public | BindingFlags.Instance, null, types2, null );
  126.       }
  127.  
  128.       public static int IntersectWith( this Entity entity, Entity other, Intersect intersectType, Point3dCollection points )
  129.       {
  130.          int start = points.Count;
  131.          object[] args = null;
  132.          if( IntPtr.Size > 4 )
  133.             args = new object[] { other, intersectType, points, (Int64) 0, (Int64) 0 };
  134.          else
  135.             args = new object[] { other, intersectType, points, (Int32) 0, (Int32) 0 };
  136.          intersectWithMethod1.Invoke( entity, args );
  137.          return points.Count - start;
  138.       }
  139.  
  140.       public static int IntersectWith( this Entity entity, Entity other, Intersect intersectType, Point3dCollection points, IntPtr thisGsMarker, IntPtr otherGsMarker )
  141.       {
  142.          int start = points.Count;
  143.          object[] args = null;
  144.          if( IntPtr.Size > 4 )
  145.             args = new object[] { other, intersectType, points, thisGsMarker.ToInt64(), otherGsMarker.ToInt64() };
  146.          else
  147.             args = new object[] { other, intersectType, points, thisGsMarker.ToInt32(), otherGsMarker.ToInt32() };
  148.          intersectWithMethod1.Invoke( entity, args );
  149.          return points.Count - start;
  150.       }
  151.  
  152.       public static int IntersectWith( this Entity entity, Entity other, Intersect intersectType, Plane plane, Point3dCollection points )
  153.       {
  154.          int start = points.Count;
  155.          object[] args = null;
  156.          if( IntPtr.Size > 4 )
  157.             args = new object[] { other, intersectType, plane, points, (Int64) 0, (Int64) 0 };
  158.          else
  159.             args = new object[] { other, intersectType, plane, points, (Int32) 0, (Int32) 0 };
  160.          intersectWithMethod2.Invoke( entity, args );
  161.          return points.Count - start;
  162.       }
  163.  
  164.       public static int IntersectWith( this Entity entity, Entity other, Intersect intersectType, Plane plane, Point3dCollection points, IntPtr thisGsMarker, IntPtr otherGsMarker )
  165.       {
  166.          int start = points.Count;
  167.          object[] args = null;
  168.          if( IntPtr.Size > 4 )
  169.             args = new object[] { other, intersectType, plane, points, thisGsMarker.ToInt64(), otherGsMarker.ToInt64() };
  170.          else
  171.             args = new object[] { other, intersectType, plane, points, thisGsMarker.ToInt32(), otherGsMarker.ToInt32() };
  172.          intersectWithMethod2.Invoke( entity, args );
  173.          return points.Count - start;
  174.       }
  175.  
  176.       static MethodInfo intersectWithMethod1 = null;
  177.       static MethodInfo intersectWithMethod2 = null;
  178.  
  179.  
  180.    }
  181. }
  182.