Fix SubsessionEventInfoNative struct definition and usage (#3)
authoradaszkiewicza <73039302+adaszkiewicza@users.noreply.github.com>
Fri, 28 Apr 2023 12:40:03 +0000 (14:40 +0200)
committerChanwoo Choi <chanwoo@kernel.org>
Mon, 15 May 2023 02:58:09 +0000 (11:58 +0900)
Now it does not use unrolled arrays

src/Tizen.System.Session/Interop/Interop.Session.cs
src/Tizen.System.Session/Session/Session.cs
src/Tizen.System.Session/Session/SessionEventArgs.cs
src/Tizen.System.Session/Session/SessionStructs.cs

index 8c15884..796d852 100644 (file)
@@ -27,7 +27,7 @@ internal static partial class Interop
         public delegate void SubsessionReplyCallback(int result, IntPtr cb_data);
 
         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
-        public delegate void SubsessionEventCallback(SubsessionEventInfoNative info, IntPtr cb_data);
+        public delegate void SubsessionEventCallback(IntPtr info, IntPtr cb_data);
 
         [DllImport(Libraries.Session, EntryPoint = "subsession_add_user", CallingConvention = CallingConvention.Cdecl)]
         public static extern SessionError SubsessionAddUser(int session_uid, string user, SubsessionReplyCallback cb, IntPtr data);
index cee9c1d..26d086a 100644 (file)
@@ -57,7 +57,7 @@ namespace Tizen.System
 
         private int _replyID = 0;
 
-        private delegate void EventDelegate(SubsessionEventInfoNative infoNative, IntPtr data);
+        private delegate void EventDelegate(IntPtr infoNative, IntPtr data);
 
         static Session()
         {
@@ -300,7 +300,7 @@ namespace Tizen.System
             CheckError(ret, $"Interop failed to mark this client's event (of type {subsessionEventArgs.SessionInfo.eventType}) as finished");
         }
 
-        private void OnAddUserWait(SubsessionEventInfoNative infoNative, IntPtr data)
+        private void OnAddUserWait(IntPtr infoNative, IntPtr data)
         {
             _addUserWaitHandler?.Invoke(this, new AddUserEventArgs(infoNative));
         }
@@ -342,7 +342,7 @@ namespace Tizen.System
             }
         }
 
-        private void OnRemoveUserWait(SubsessionEventInfoNative infoNative, IntPtr data)
+        private void OnRemoveUserWait(IntPtr infoNative, IntPtr data)
         {
             _removeUserWaitHandler?.Invoke(this, new RemoveUserEventArgs(infoNative));
         }
@@ -384,7 +384,7 @@ namespace Tizen.System
             }
         }
 
-        private void OnSwitchUserWait(SubsessionEventInfoNative infoNative, IntPtr data)
+        private void OnSwitchUserWait(IntPtr infoNative, IntPtr data)
         {
             _switchUserWaitHandler?.Invoke(this, new SwitchUserWaitEventArgs(infoNative));
         }
@@ -426,7 +426,7 @@ namespace Tizen.System
             }
         }
 
-        private void OnSwitchUserCompletion(SubsessionEventInfoNative infoNative, IntPtr data)
+        private void OnSwitchUserCompletion(IntPtr infoNative, IntPtr data)
         {
             _switchUserCompletionHandler?.Invoke(this, new SwitchUserCompletionEventArgs(infoNative));
         }
@@ -488,7 +488,7 @@ namespace Tizen.System
         {
             managedArray = new string[size]; 
             var curr = unmanagedArray;
-            
+
             for (int iterator = 0; iterator < size; iterator++)
             {
                 managedArray[iterator] = Marshal.PtrToStringAnsi(curr, 20);
index b30bd87..07f4484 100644 (file)
@@ -16,6 +16,7 @@
 
 using System;
 using System.ComponentModel;
+using System.Runtime.InteropServices;
 
 namespace Tizen.System
 {
@@ -38,10 +39,10 @@ namespace Tizen.System
 
         internal SubsessionEventInfoNative SessionInfo { get; set; }
 
-        internal SubsessionEventArgs(SubsessionEventInfoNative infoNative)
+        internal SubsessionEventArgs(IntPtr infoNativePtr)
         {
-            SessionUID = infoNative.sessionUID;
-            SessionInfo = infoNative;
+            SessionInfo = (SubsessionEventInfoNative)Marshal.PtrToStructure(infoNativePtr, typeof(SubsessionEventInfoNative));
+            SessionUID = SessionInfo.sessionUID;
         }
     }
 
@@ -57,10 +58,10 @@ namespace Tizen.System
         [EditorBrowsable(EditorBrowsableState.Never)]
         public string UserName { get; internal set; }
 
-        internal AddUserEventArgs(SubsessionEventInfoNative infoNative)
-            : base(infoNative)
+        internal AddUserEventArgs(IntPtr infoNativePtr)
+            : base(infoNativePtr)
         {
-            UserName = infoNative.addUser.userName;
+            UserName = Marshal.PtrToStringAnsi(IntPtr.Add(infoNativePtr, 8), 20);
         }
     }
 
@@ -76,10 +77,10 @@ namespace Tizen.System
         [EditorBrowsable(EditorBrowsableState.Never)]
         public string UserName { get; internal set; }
 
-        internal RemoveUserEventArgs(SubsessionEventInfoNative infoNative)
-            : base(infoNative)
+        internal RemoveUserEventArgs(IntPtr infoNativePtr)
+            : base(infoNativePtr)
         {
-            UserName = infoNative.removeUser.userName;
+            UserName = Marshal.PtrToStringAnsi(IntPtr.Add(infoNativePtr, 8), 20);
         }
     }
 
@@ -107,12 +108,12 @@ namespace Tizen.System
         [EditorBrowsable(EditorBrowsableState.Never)]
         public string UserNameNext { get; internal set; }
 
-        internal SwitchUserEventArgs(SubsessionEventInfoNative infoNative)
-            : base(infoNative)
+        internal SwitchUserEventArgs(IntPtr infoNativePtr)
+            : base(infoNativePtr)
         {
-            SwitchID = infoNative.switchUser.switchID;
-            UserNamePrev = infoNative.switchUser.userNamePrev;
-            UserNameNext = infoNative.switchUser.userNameNext;
+            SwitchID = SessionInfo.switchID;
+            UserNamePrev = Marshal.PtrToStringAnsi(IntPtr.Add(infoNativePtr, 16), 20);
+            UserNameNext = Marshal.PtrToStringAnsi(IntPtr.Add(infoNativePtr, 36), 20);
         }
     }
 
@@ -122,7 +123,7 @@ namespace Tizen.System
     [EditorBrowsable(EditorBrowsableState.Never)]
     public class SwitchUserWaitEventArgs : SwitchUserEventArgs
     {
-        internal SwitchUserWaitEventArgs(SubsessionEventInfoNative infoNative) : base(infoNative) { }
+        internal SwitchUserWaitEventArgs(IntPtr infoNativePtr) : base(infoNativePtr) { }
     }
 
     /// <summary>
@@ -131,6 +132,6 @@ namespace Tizen.System
     [EditorBrowsable(EditorBrowsableState.Never)]
     public class SwitchUserCompletionEventArgs : SwitchUserEventArgs
     {
-        internal SwitchUserCompletionEventArgs(SubsessionEventInfoNative infoNative) : base(infoNative) { }
+        internal SwitchUserCompletionEventArgs(IntPtr infoNativePtr) : base(infoNativePtr) { }
     }
 }
index b0db254..f68d06a 100644 (file)
@@ -22,7 +22,7 @@ using Tizen.Internals;
 
 namespace Tizen.System
 {
-    [NativeStruct("subsession_event_info", Include = "sessiond.h", PkgConfig = "libsessiond")]
+    [NativeStruct("subsession_event_info", Include="sessiond.h", PkgConfig="libsessiond")]
     [StructLayout(LayoutKind.Explicit)]
     internal struct SubsessionEventInfoNative
     {
@@ -30,205 +30,19 @@ namespace Tizen.System
         public SessionEventType eventType;
         [FieldOffset(4)]
         public int sessionUID;
-        [FieldOffset(8)]
-        public AddUser addUser;
-        [FieldOffset(8)]
-        public RemoveUser removeUser;
-        [FieldOffset(8)]
-        public SwitchUser switchUser;
-    }
-
-    /*
-
-       Regarding AddUser, RemoveUser and SwitchUser structs:
 
-       Marshaling complex C/C++ structs containing C/C++ unions as their members is tricky.
-       Firstly, to handle C/C++ unions in C# one needs to provide an explicit memory layout.
-       It's vital to provide a correct alignment. Since our fields in the native C struct being
-       reflected here are already all divisible by 4, there's no need for fillers.
-       Secondly, when the C# marshaller encounters an array, it creates a managed counterpart
-       on the heap, but what we'll get on the stack is actually the reference to the array on the heap.
-       Any other structure containing basic types would be overlapping and thus invalidating that
-       reference (remember we're dealing with a union where all the elements (structs in our case)
-       start form the same address) and leading to a nasty run-time error:
-       "it contains an object field at offset X that is incorrectly aligned
-       or overlapped by a non-object field".
-       The only solution that works 100% of the times is unrolling the arrays down to
-       single bytes and turn off the C# marshaller.
-       Unfortunately the code is not pretty, but they say maturity is consent to an unfulfilled life.
-
-       */
-
-    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
-    internal struct AddUser
-    {
-        public byte userName_00;
-        public byte userName_01;
-        public byte userName_02;
-        public byte userName_03;
-        public byte userName_04;
-        public byte userName_05;
-        public byte userName_06;
-        public byte userName_07;
-        public byte userName_08;
-        public byte userName_09;
-        public byte userName_10;
-        public byte userName_11;
-        public byte userName_12;
-        public byte userName_13;
-        public byte userName_14;
-        public byte userName_15;
-        public byte userName_16;
-        public byte userName_17;
-        public byte userName_18;
-        public byte userName_19;
+        [FieldOffset(8)]
+        public IntPtr AddUserPtr;
 
-        public string userName
-        {
-            get
-            {
-                return UnrolledBytesToStringConverter.Convert20(
-                    userName_00, userName_01, userName_02, userName_03,
-                    userName_04, userName_05, userName_06, userName_07,
-                    userName_08, userName_09, userName_10, userName_11,
-                    userName_12, userName_13, userName_14, userName_15,
-                    userName_16, userName_17, userName_18, userName_19
-                );
-            }
-        }
-    }
+        [FieldOffset(8)]
+        public IntPtr RemoveUserPtr;
 
-    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
-    internal struct RemoveUser
-    {
-        public byte userName_00;
-        public byte userName_01;
-        public byte userName_02;
-        public byte userName_03;
-        public byte userName_04;
-        public byte userName_05;
-        public byte userName_06;
-        public byte userName_07;
-        public byte userName_08;
-        public byte userName_09;
-        public byte userName_10;
-        public byte userName_11;
-        public byte userName_12;
-        public byte userName_13;
-        public byte userName_14;
-        public byte userName_15;
-        public byte userName_16;
-        public byte userName_17;
-        public byte userName_18;
-        public byte userName_19;
-        public string userName
-        {
-            get
-            {
-                return UnrolledBytesToStringConverter.Convert20(
-                    userName_00, userName_01, userName_02, userName_03,
-                    userName_04, userName_05, userName_06, userName_07,
-                    userName_08, userName_09, userName_10, userName_11,
-                    userName_12, userName_13, userName_14, userName_15,
-                    userName_16, userName_17, userName_18, userName_19
-                );
-            }
-        }
-    }
-    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)]
-    internal struct SwitchUser
-    {
+        [FieldOffset(8)]
         public Int64 switchID;
-        public byte userNamePrev_00;
-        public byte userNamePrev_01;
-        public byte userNamePrev_02;
-        public byte userNamePrev_03;
-        public byte userNamePrev_04;
-        public byte userNamePrev_05;
-        public byte userNamePrev_06;
-        public byte userNamePrev_07;
-        public byte userNamePrev_08;
-        public byte userNamePrev_09;
-        public byte userNamePrev_10;
-        public byte userNamePrev_11;
-        public byte userNamePrev_12;
-        public byte userNamePrev_13;
-        public byte userNamePrev_14;
-        public byte userNamePrev_15;
-        public byte userNamePrev_16;
-        public byte userNamePrev_17;
-        public byte userNamePrev_18;
-        public byte userNamePrev_19;
-
-        public string userNamePrev
-        {
-            get
-            {
-                return UnrolledBytesToStringConverter.Convert20(
-                    userNamePrev_00, userNamePrev_01, userNamePrev_02, userNamePrev_03,
-                    userNamePrev_04, userNamePrev_05, userNamePrev_06, userNamePrev_07,
-                    userNamePrev_08, userNamePrev_09, userNamePrev_10, userNamePrev_11,
-                    userNamePrev_12, userNamePrev_13, userNamePrev_14, userNamePrev_15,
-                    userNamePrev_16, userNamePrev_17, userNamePrev_18, userNamePrev_19
-                );
-            }
-        }
-
-        public byte userNameNext_00;
-        public byte userNameNext_01;
-        public byte userNameNext_02;
-        public byte userNameNext_03;
-        public byte userNameNext_04;
-        public byte userNameNext_05;
-        public byte userNameNext_06;
-        public byte userNameNext_07;
-        public byte userNameNext_08;
-        public byte userNameNext_09;
-        public byte userNameNext_10;
-        public byte userNameNext_11;
-        public byte userNameNext_12;
-        public byte userNameNext_13;
-        public byte userNameNext_14;
-        public byte userNameNext_15;
-        public byte userNameNext_16;
-        public byte userNameNext_17;
-        public byte userNameNext_18;
-        public byte userNameNext_19;
-
-        public string userNameNext
-        {
-            get
-            {
-                return UnrolledBytesToStringConverter.Convert20(
-                    userNameNext_00, userNameNext_01, userNameNext_02, userNameNext_03,
-                    userNameNext_04, userNameNext_05, userNameNext_06, userNameNext_07,
-                    userNameNext_08, userNameNext_09, userNameNext_10, userNameNext_11,
-                    userNameNext_12, userNameNext_13, userNameNext_14, userNameNext_15,
-                    userNameNext_16, userNameNext_17, userNameNext_18, userNameNext_19
-                );
-            }
-        }
-    }
-
-    internal static class UnrolledBytesToStringConverter
-    {
-        public static string Convert20(
-            byte val_00, byte val_01, byte val_02, byte val_03,
-            byte val_04, byte val_05, byte val_06, byte val_07,
-            byte val_08, byte val_09, byte val_10, byte val_11,
-            byte val_12, byte val_13, byte val_14, byte val_15,
-            byte val_16, byte val_17, byte val_18, byte val_19)
-        {
-            byte[] toConvert = new byte[]
-            {
-                    val_00, val_01, val_02, val_03,
-                    val_04, val_05, val_06, val_07,
-                    val_08, val_09, val_10, val_11,
-                    val_12, val_13, val_14, val_15,
-                    val_16, val_17, val_18, val_19
-            };
-
-            return Encoding.UTF8.GetString(toConvert);
-        }
+        [FieldOffset(16)]
+        public IntPtr PrevUserPtr;
+        
+        [FieldOffset(36)]
+        public IntPtr NextUserPtr;
     }
 }