diff --git a/libs/UGridNET/dll/CMakeLists.txt b/libs/UGridNET/dll/CMakeLists.txt index 6d56bed..c98821b 100644 --- a/libs/UGridNET/dll/CMakeLists.txt +++ b/libs/UGridNET/dll/CMakeLists.txt @@ -51,8 +51,8 @@ set( SOURCES ${SWIG_GENERATED_CSHARP_SRCS} ${SOURCE_DIR}/ContactsExtensions.cs - ${SOURCE_DIR}/ExtensionsConstants.cs ${SOURCE_DIR}/IntPtrExtensions.cs + ${SOURCE_DIR}/IntPtrHelpers.cs ${SOURCE_DIR}/Mesh1DExtensions.cs ${SOURCE_DIR}/Mesh2DExtensions.cs ${SOURCE_DIR}/Network1DExtensions.cs diff --git a/libs/UGridNET/dll/src/ContactsExtensions.cs b/libs/UGridNET/dll/src/ContactsExtensions.cs index 18827dd..09b4aab 100644 --- a/libs/UGridNET/dll/src/ContactsExtensions.cs +++ b/libs/UGridNET/dll/src/ContactsExtensions.cs @@ -9,24 +9,33 @@ internal static class ContactsExtensions { public static void Allocate(this Contacts contacts) { - contacts.name = Marshal.AllocHGlobal(UGrid.name_long_length); - contacts.contact_name_id = Marshal.AllocHGlobal(UGrid.name_length * contacts.num_contacts); - contacts.mesh_from_name = Marshal.AllocHGlobal(UGrid.name_long_length); - contacts.mesh_to_name = Marshal.AllocHGlobal(UGrid.name_long_length); - contacts.contact_name_long = Marshal.AllocHGlobal(UGrid.name_long_length * contacts.num_contacts); - contacts.edges = Marshal.AllocHGlobal(contacts.num_contacts * 2 * Constants.intBytes); - contacts.contact_type = Marshal.AllocHGlobal(contacts.num_contacts * Constants.intBytes); + try + { + contacts.name = IntPtrHelpers.Allocate(UGrid.name_long_length); + contacts.contact_name_id = IntPtrHelpers.Allocate(UGrid.name_length * contacts.num_contacts); + contacts.mesh_from_name = IntPtrHelpers.Allocate(UGrid.name_long_length); + contacts.mesh_to_name = IntPtrHelpers.Allocate(UGrid.name_long_length); + contacts.contact_name_long = IntPtrHelpers.Allocate(UGrid.name_long_length * contacts.num_contacts); + contacts.edges = IntPtrHelpers.Allocate(contacts.num_contacts * 2 * IntPtrHelpers.Constants.intBytes); + contacts.contact_type = IntPtrHelpers.Allocate(contacts.num_contacts * IntPtrHelpers.Constants.intBytes); + } + catch + { + // AllocHGlobal may throw OutOfMemoryException exception, clean up and re-throw + contacts.Free(); + throw; + } } public static void Free(this Contacts contacts) { - if (contacts.name != IntPtr.Zero) Marshal.FreeHGlobal(contacts.name); - if (contacts.contact_name_id != IntPtr.Zero) Marshal.FreeHGlobal(contacts.contact_name_id); - if (contacts.mesh_from_name != IntPtr.Zero) Marshal.FreeHGlobal(contacts.mesh_from_name); - if (contacts.mesh_to_name != IntPtr.Zero) Marshal.FreeHGlobal(contacts.mesh_to_name); - if (contacts.contact_name_long != IntPtr.Zero) Marshal.FreeHGlobal(contacts.contact_name_long); - if (contacts.edges != IntPtr.Zero) Marshal.FreeHGlobal(contacts.edges); - if (contacts.contact_type != IntPtr.Zero) Marshal.FreeHGlobal(contacts.contact_type); + IntPtrHelpers.Free(contacts.name); + IntPtrHelpers.Free(contacts.contact_name_id); + IntPtrHelpers.Free(contacts.mesh_from_name); + IntPtrHelpers.Free(contacts.mesh_to_name); + IntPtrHelpers.Free(contacts.contact_name_long); + IntPtrHelpers.Free(contacts.edges); + IntPtrHelpers.Free(contacts.contact_type); } } } diff --git a/libs/UGridNET/dll/src/ExtensionsConstants.cs b/libs/UGridNET/dll/src/IntPtrHelpers.cs similarity index 50% rename from libs/UGridNET/dll/src/ExtensionsConstants.cs rename to libs/UGridNET/dll/src/IntPtrHelpers.cs index 8a5a078..24a2b87 100644 --- a/libs/UGridNET/dll/src/ExtensionsConstants.cs +++ b/libs/UGridNET/dll/src/IntPtrHelpers.cs @@ -3,7 +3,7 @@ namespace UGridNET { - namespace Extensions + internal static class IntPtrHelpers { internal static class Constants { @@ -11,5 +11,19 @@ internal static class Constants public static readonly int doubleBytes = Marshal.SizeOf(); public static readonly int byteBytes = Marshal.SizeOf(); } + public static IntPtr Allocate(int size) + { + return Marshal.AllocHGlobal(size); + } + + public static void Free(IntPtr ptr) + { + if (ptr != IntPtr.Zero) + { + Marshal.FreeHGlobal(ptr); + ptr = IntPtr.Zero; + } + } } + } \ No newline at end of file diff --git a/libs/UGridNET/dll/src/Mesh1DExtensions.cs b/libs/UGridNET/dll/src/Mesh1DExtensions.cs index c06869e..d7e5b3e 100644 --- a/libs/UGridNET/dll/src/Mesh1DExtensions.cs +++ b/libs/UGridNET/dll/src/Mesh1DExtensions.cs @@ -9,32 +9,41 @@ internal static class Mesh1DExtensions { public static void Allocate(this Mesh1D mesh1D) { - mesh1D.name = Marshal.AllocHGlobal(UGrid.name_long_length); - mesh1D.node_long_name = Marshal.AllocHGlobal(UGrid.name_long_length * mesh1D.num_nodes); - mesh1D.network_name = Marshal.AllocHGlobal(UGrid.name_long_length); - mesh1D.node_x = Marshal.AllocHGlobal(mesh1D.num_nodes * Constants.doubleBytes); - mesh1D.node_y = Marshal.AllocHGlobal(mesh1D.num_nodes * Constants.doubleBytes); - mesh1D.edge_x = Marshal.AllocHGlobal(mesh1D.num_edges * Constants.doubleBytes); - mesh1D.edge_y = Marshal.AllocHGlobal(mesh1D.num_edges * Constants.doubleBytes); - mesh1D.edge_nodes = Marshal.AllocHGlobal(mesh1D.num_edges * 2 * Constants.intBytes); - mesh1D.edge_edge_id = Marshal.AllocHGlobal(mesh1D.num_nodes * Constants.intBytes); // size? - mesh1D.node_edge_id = Marshal.AllocHGlobal(mesh1D.num_nodes * Constants.intBytes); // size? - mesh1D.node_edge_offset = Marshal.AllocHGlobal(mesh1D.num_nodes * Constants.doubleBytes); + try + { + mesh1D.name = IntPtrHelpers.Allocate(UGrid.name_long_length); + mesh1D.node_long_name = IntPtrHelpers.Allocate(UGrid.name_long_length * mesh1D.num_nodes); + mesh1D.network_name = IntPtrHelpers.Allocate(UGrid.name_long_length); + mesh1D.node_x = IntPtrHelpers.Allocate(mesh1D.num_nodes * IntPtrHelpers.Constants.doubleBytes); + mesh1D.node_y = IntPtrHelpers.Allocate(mesh1D.num_nodes * IntPtrHelpers.Constants.doubleBytes); + mesh1D.edge_x = IntPtrHelpers.Allocate(mesh1D.num_edges * IntPtrHelpers.Constants.doubleBytes); + mesh1D.edge_y = IntPtrHelpers.Allocate(mesh1D.num_edges * IntPtrHelpers.Constants.doubleBytes); + mesh1D.edge_nodes = IntPtrHelpers.Allocate(mesh1D.num_edges * 2 * IntPtrHelpers.Constants.intBytes); + mesh1D.edge_edge_id = IntPtrHelpers.Allocate(mesh1D.num_nodes * IntPtrHelpers.Constants.intBytes); // size? + mesh1D.node_edge_id = IntPtrHelpers.Allocate(mesh1D.num_nodes * IntPtrHelpers.Constants.intBytes); // size? + mesh1D.node_edge_offset = IntPtrHelpers.Allocate(mesh1D.num_nodes * IntPtrHelpers.Constants.doubleBytes); + } + catch + { + // AllocHGlobal may throw OutOfMemoryException exception, clean up and re-throw + mesh1D.Free(); + throw; + } } public static void Free(this Mesh1D mesh1D) { - if (mesh1D.name != IntPtr.Zero) Marshal.FreeHGlobal(mesh1D.name); - if (mesh1D.node_long_name != IntPtr.Zero) Marshal.FreeHGlobal(mesh1D.node_long_name); - if (mesh1D.network_name != IntPtr.Zero) Marshal.FreeHGlobal(mesh1D.network_name); - if (mesh1D.node_x != IntPtr.Zero) Marshal.FreeHGlobal(mesh1D.node_x); - if (mesh1D.node_y != IntPtr.Zero) Marshal.FreeHGlobal(mesh1D.node_y); - if (mesh1D.edge_x != IntPtr.Zero) Marshal.FreeHGlobal(mesh1D.edge_x); - if (mesh1D.edge_y != IntPtr.Zero) Marshal.FreeHGlobal(mesh1D.edge_y); - if (mesh1D.edge_nodes != IntPtr.Zero) Marshal.FreeHGlobal(mesh1D.edge_nodes); - if (mesh1D.edge_edge_id != IntPtr.Zero) Marshal.FreeHGlobal(mesh1D.edge_edge_id); - if (mesh1D.node_edge_id != IntPtr.Zero) Marshal.FreeHGlobal(mesh1D.node_edge_id); - if (mesh1D.node_edge_offset != IntPtr.Zero) Marshal.FreeHGlobal(mesh1D.node_edge_offset); + IntPtrHelpers.Free(mesh1D.name); + IntPtrHelpers.Free(mesh1D.node_long_name); + IntPtrHelpers.Free(mesh1D.network_name); + IntPtrHelpers.Free(mesh1D.node_x); + IntPtrHelpers.Free(mesh1D.node_y); + IntPtrHelpers.Free(mesh1D.edge_x); + IntPtrHelpers.Free(mesh1D.edge_y); + IntPtrHelpers.Free(mesh1D.edge_nodes); + IntPtrHelpers.Free(mesh1D.edge_edge_id); + IntPtrHelpers.Free(mesh1D.node_edge_id); + IntPtrHelpers.Free(mesh1D.node_edge_offset); } } } diff --git a/libs/UGridNET/dll/src/Mesh2DExtensions.cs b/libs/UGridNET/dll/src/Mesh2DExtensions.cs index e89646d..cb4e549 100644 --- a/libs/UGridNET/dll/src/Mesh2DExtensions.cs +++ b/libs/UGridNET/dll/src/Mesh2DExtensions.cs @@ -9,40 +9,49 @@ internal static class Mesh2DExtensions { public static void Allocate(this Mesh2D mesh2D) { - mesh2D.name = Marshal.AllocHGlobal(UGrid.name_long_length); - mesh2D.node_x = Marshal.AllocHGlobal(mesh2D.num_nodes * Constants.doubleBytes); - mesh2D.node_y = Marshal.AllocHGlobal(mesh2D.num_nodes * Constants.doubleBytes); - mesh2D.node_z = Marshal.AllocHGlobal(mesh2D.num_nodes * Constants.doubleBytes); - mesh2D.edge_x = Marshal.AllocHGlobal(mesh2D.num_edges * Constants.doubleBytes); - mesh2D.edge_y = Marshal.AllocHGlobal(mesh2D.num_edges * Constants.doubleBytes); - mesh2D.edge_z = Marshal.AllocHGlobal(mesh2D.num_edges * Constants.doubleBytes); - mesh2D.face_x = Marshal.AllocHGlobal(mesh2D.num_faces * Constants.doubleBytes); - mesh2D.face_y = Marshal.AllocHGlobal(mesh2D.num_faces * Constants.doubleBytes); - mesh2D.face_z = Marshal.AllocHGlobal(mesh2D.num_faces * Constants.doubleBytes); - mesh2D.edge_nodes = Marshal.AllocHGlobal(mesh2D.num_edges * 2 * Constants.intBytes); - mesh2D.edge_faces = Marshal.AllocHGlobal(mesh2D.num_edges * 2 * Constants.intBytes); - mesh2D.face_nodes = Marshal.AllocHGlobal(mesh2D.num_faces * mesh2D.num_face_nodes_max * Constants.intBytes); - mesh2D.face_edges = Marshal.AllocHGlobal(mesh2D.num_faces * mesh2D.num_face_nodes_max * Constants.intBytes); - mesh2D.face_faces = Marshal.AllocHGlobal(mesh2D.num_faces * mesh2D.num_face_nodes_max * Constants.intBytes); + try + { + mesh2D.name = IntPtrHelpers.Allocate(UGrid.name_long_length); + mesh2D.node_x = IntPtrHelpers.Allocate(mesh2D.num_nodes * IntPtrHelpers.Constants.doubleBytes); + mesh2D.node_y = IntPtrHelpers.Allocate(mesh2D.num_nodes * IntPtrHelpers.Constants.doubleBytes); + mesh2D.node_z = IntPtrHelpers.Allocate(mesh2D.num_nodes * IntPtrHelpers.Constants.doubleBytes); + mesh2D.edge_x = IntPtrHelpers.Allocate(mesh2D.num_edges * IntPtrHelpers.Constants.doubleBytes); + mesh2D.edge_y = IntPtrHelpers.Allocate(mesh2D.num_edges * IntPtrHelpers.Constants.doubleBytes); + mesh2D.edge_z = IntPtrHelpers.Allocate(mesh2D.num_edges * IntPtrHelpers.Constants.doubleBytes); + mesh2D.face_x = IntPtrHelpers.Allocate(mesh2D.num_faces * IntPtrHelpers.Constants.doubleBytes); + mesh2D.face_y = IntPtrHelpers.Allocate(mesh2D.num_faces * IntPtrHelpers.Constants.doubleBytes); + mesh2D.face_z = IntPtrHelpers.Allocate(mesh2D.num_faces * IntPtrHelpers.Constants.doubleBytes); + mesh2D.edge_nodes = IntPtrHelpers.Allocate(mesh2D.num_edges * 2 * IntPtrHelpers.Constants.intBytes); + mesh2D.edge_faces = IntPtrHelpers.Allocate(mesh2D.num_edges * 2 * IntPtrHelpers.Constants.intBytes); + mesh2D.face_nodes = IntPtrHelpers.Allocate(mesh2D.num_faces * mesh2D.num_face_nodes_max * IntPtrHelpers.Constants.intBytes); + mesh2D.face_edges = IntPtrHelpers.Allocate(mesh2D.num_faces * mesh2D.num_face_nodes_max * IntPtrHelpers.Constants.intBytes); + mesh2D.face_faces = IntPtrHelpers.Allocate(mesh2D.num_faces * mesh2D.num_face_nodes_max * IntPtrHelpers.Constants.intBytes); + } + catch + { + // AllocHGlobal may throw OutOfMemoryException exception, clean up and re-throw + mesh2D.Free(); + throw; + } } public static void Free(this Mesh2D mesh2D) { - if (mesh2D.name != IntPtr.Zero) Marshal.FreeHGlobal(mesh2D.name); - if (mesh2D.node_x != IntPtr.Zero) Marshal.FreeHGlobal(mesh2D.node_x); - if (mesh2D.node_y != IntPtr.Zero) Marshal.FreeHGlobal(mesh2D.node_y); - if (mesh2D.node_z != IntPtr.Zero) Marshal.FreeHGlobal(mesh2D.node_z); - if (mesh2D.edge_x != IntPtr.Zero) Marshal.FreeHGlobal(mesh2D.edge_x); - if (mesh2D.edge_y != IntPtr.Zero) Marshal.FreeHGlobal(mesh2D.edge_y); - if (mesh2D.edge_z != IntPtr.Zero) Marshal.FreeHGlobal(mesh2D.edge_z); - if (mesh2D.face_x != IntPtr.Zero) Marshal.FreeHGlobal(mesh2D.face_x); - if (mesh2D.face_y != IntPtr.Zero) Marshal.FreeHGlobal(mesh2D.face_y); - if (mesh2D.face_z != IntPtr.Zero) Marshal.FreeHGlobal(mesh2D.face_z); - if (mesh2D.edge_nodes != IntPtr.Zero) Marshal.FreeHGlobal(mesh2D.edge_nodes); - if (mesh2D.edge_faces != IntPtr.Zero) Marshal.FreeHGlobal(mesh2D.edge_faces); - if (mesh2D.face_nodes != IntPtr.Zero) Marshal.FreeHGlobal(mesh2D.face_nodes); - if (mesh2D.face_edges != IntPtr.Zero) Marshal.FreeHGlobal(mesh2D.face_edges); - if (mesh2D.face_faces != IntPtr.Zero) Marshal.FreeHGlobal(mesh2D.face_faces); + IntPtrHelpers.Free(mesh2D.name); + IntPtrHelpers.Free(mesh2D.node_x); + IntPtrHelpers.Free(mesh2D.node_y); + IntPtrHelpers.Free(mesh2D.node_z); + IntPtrHelpers.Free(mesh2D.edge_x); + IntPtrHelpers.Free(mesh2D.edge_y); + IntPtrHelpers.Free(mesh2D.edge_z); + IntPtrHelpers.Free(mesh2D.face_x); + IntPtrHelpers.Free(mesh2D.face_y); + IntPtrHelpers.Free(mesh2D.face_z); + IntPtrHelpers.Free(mesh2D.edge_nodes); + IntPtrHelpers.Free(mesh2D.edge_faces); + IntPtrHelpers.Free(mesh2D.face_nodes); + IntPtrHelpers.Free(mesh2D.face_edges); + IntPtrHelpers.Free(mesh2D.face_faces); } } } diff --git a/libs/UGridNET/dll/src/Network1DExtensions.cs b/libs/UGridNET/dll/src/Network1DExtensions.cs index 0b4c6e7..80e0f54 100644 --- a/libs/UGridNET/dll/src/Network1DExtensions.cs +++ b/libs/UGridNET/dll/src/Network1DExtensions.cs @@ -9,36 +9,45 @@ internal static class Network1DExtensions { public static void Allocate(this Network1D network1D) { - network1D.name = Marshal.AllocHGlobal(UGrid.name_long_length); - network1D.node_id = Marshal.AllocHGlobal(UGrid.name_length * network1D.num_nodes); - network1D.node_long_name = Marshal.AllocHGlobal(UGrid.name_long_length * network1D.num_nodes); - network1D.edge_id = Marshal.AllocHGlobal(UGrid.name_length * network1D.num_edges); - network1D.edge_long_name = Marshal.AllocHGlobal(UGrid.name_long_length * network1D.num_edges); - network1D.node_x = Marshal.AllocHGlobal(network1D.num_nodes * Constants.doubleBytes); - network1D.node_y = Marshal.AllocHGlobal(network1D.num_nodes * Constants.doubleBytes); - network1D.edge_nodes = Marshal.AllocHGlobal(network1D.num_edges * 2 * Constants.intBytes); - network1D.edge_length = Marshal.AllocHGlobal(network1D.num_edges * Constants.doubleBytes); - network1D.edge_order = Marshal.AllocHGlobal(network1D.num_edges * Constants.intBytes); - network1D.geometry_nodes_x = Marshal.AllocHGlobal(network1D.num_geometry_nodes * Constants.doubleBytes); - network1D.geometry_nodes_y = Marshal.AllocHGlobal(network1D.num_geometry_nodes * Constants.doubleBytes); - network1D.num_edge_geometry_nodes = Marshal.AllocHGlobal(network1D.num_edges * Constants.intBytes); + try + { + network1D.name = IntPtrHelpers.Allocate(UGrid.name_long_length); + network1D.node_id = IntPtrHelpers.Allocate(UGrid.name_length * network1D.num_nodes); + network1D.node_long_name = IntPtrHelpers.Allocate(UGrid.name_long_length * network1D.num_nodes); + network1D.edge_id = IntPtrHelpers.Allocate(UGrid.name_length * network1D.num_edges); + network1D.edge_long_name = IntPtrHelpers.Allocate(UGrid.name_long_length * network1D.num_edges); + network1D.node_x = IntPtrHelpers.Allocate(network1D.num_nodes * IntPtrHelpers.Constants.doubleBytes); + network1D.node_y = IntPtrHelpers.Allocate(network1D.num_nodes * IntPtrHelpers.Constants.doubleBytes); + network1D.edge_nodes = IntPtrHelpers.Allocate(network1D.num_edges * 2 * IntPtrHelpers.Constants.intBytes); + network1D.edge_length = IntPtrHelpers.Allocate(network1D.num_edges * IntPtrHelpers.Constants.doubleBytes); + network1D.edge_order = IntPtrHelpers.Allocate(network1D.num_edges * IntPtrHelpers.Constants.intBytes); + network1D.geometry_nodes_x = IntPtrHelpers.Allocate(network1D.num_geometry_nodes * IntPtrHelpers.Constants.doubleBytes); + network1D.geometry_nodes_y = IntPtrHelpers.Allocate(network1D.num_geometry_nodes * IntPtrHelpers.Constants.doubleBytes); + network1D.num_edge_geometry_nodes = IntPtrHelpers.Allocate(network1D.num_edges * IntPtrHelpers.Constants.intBytes); + } + catch + { + // AllocHGlobal may throw OutOfMemoryException exception, clean up and re-throw + network1D.Free(); + throw; + } } public static void Free(this Network1D network1D) { - if (network1D.name != IntPtr.Zero) Marshal.FreeHGlobal(network1D.name); - if (network1D.node_id != IntPtr.Zero) Marshal.FreeHGlobal(network1D.node_id); - if (network1D.node_long_name != IntPtr.Zero) Marshal.FreeHGlobal(network1D.node_long_name); - if (network1D.edge_id != IntPtr.Zero) Marshal.FreeHGlobal(network1D.edge_id); - if (network1D.edge_long_name != IntPtr.Zero) Marshal.FreeHGlobal(network1D.edge_long_name); - if (network1D.node_x != IntPtr.Zero) Marshal.FreeHGlobal(network1D.node_x); - if (network1D.node_y != IntPtr.Zero) Marshal.FreeHGlobal(network1D.node_y); - if (network1D.edge_nodes != IntPtr.Zero) Marshal.FreeHGlobal(network1D.edge_nodes); - if (network1D.edge_length != IntPtr.Zero) Marshal.FreeHGlobal(network1D.edge_length); - if (network1D.edge_order != IntPtr.Zero) Marshal.FreeHGlobal(network1D.edge_order); - if (network1D.geometry_nodes_x != IntPtr.Zero) Marshal.FreeHGlobal(network1D.geometry_nodes_x); - if (network1D.geometry_nodes_y != IntPtr.Zero) Marshal.FreeHGlobal(network1D.geometry_nodes_y); - if (network1D.num_edge_geometry_nodes != IntPtr.Zero) Marshal.FreeHGlobal(network1D.num_edge_geometry_nodes); + IntPtrHelpers.Free(network1D.name); + IntPtrHelpers.Free(network1D.node_id); + IntPtrHelpers.Free(network1D.node_long_name); + IntPtrHelpers.Free(network1D.edge_id); + IntPtrHelpers.Free(network1D.edge_long_name); + IntPtrHelpers.Free(network1D.node_x); + IntPtrHelpers.Free(network1D.node_y); + IntPtrHelpers.Free(network1D.edge_nodes); + IntPtrHelpers.Free(network1D.edge_length); + IntPtrHelpers.Free(network1D.edge_order); + IntPtrHelpers.Free(network1D.geometry_nodes_x); + IntPtrHelpers.Free(network1D.geometry_nodes_y); + IntPtrHelpers.Free(network1D.num_edge_geometry_nodes); } } }