private static IntPtr BuildVTable(Callback.Run run, List <GCHandle> allocations) { Callback.RunCall runCall = new Callback.RunCall(Callback.RunStub); Callback.GetCallbackSizeBytes getCallbackSizeByte = new Callback.GetCallbackSizeBytes(Callback.SizeStub); allocations.Add(GCHandle.Alloc(run)); allocations.Add(GCHandle.Alloc(runCall)); allocations.Add(GCHandle.Alloc(getCallbackSizeByte)); IntPtr functionPointerForDelegate = Marshal.GetFunctionPointerForDelegate <Callback.Run>(run); IntPtr intPtr = Marshal.GetFunctionPointerForDelegate <Callback.RunCall>(runCall); IntPtr functionPointerForDelegate1 = Marshal.GetFunctionPointerForDelegate <Callback.GetCallbackSizeBytes>(getCallbackSizeByte); IntPtr intPtr1 = Marshal.AllocHGlobal(IntPtr.Size * 3); if (Config.Os != OsType.Windows) { int size = IntPtr.Size; Marshal.WriteIntPtr(intPtr1, 0, functionPointerForDelegate); Marshal.WriteIntPtr(intPtr1, IntPtr.Size, intPtr); Marshal.WriteIntPtr(intPtr1, IntPtr.Size * 2, functionPointerForDelegate1); } else { int num = IntPtr.Size; Marshal.WriteIntPtr(intPtr1, 0, intPtr); Marshal.WriteIntPtr(intPtr1, IntPtr.Size, functionPointerForDelegate); Marshal.WriteIntPtr(intPtr1, IntPtr.Size * 2, functionPointerForDelegate1); } return(intPtr1); }
internal static void Register(Callback.Run func, int size, int callbackId, bool gameserver) { Event @event = new Event() { vTablePtr = Event.BuildVTable(func, @event.Allocations) }; Callback callback = new Callback() { vTablePtr = @event.vTablePtr, CallbackFlags = (byte)((gameserver ? 2 : 0)), CallbackId = callbackId }; @event.PinnedCallback = GCHandle.Alloc(callback, GCHandleType.Pinned); SteamClient.RegisterCallback(@event.PinnedCallback.AddrOfPinnedObject(), callback.CallbackId); @event.IsAllocated = true; if (!gameserver) { Event.AllClient.Add(@event); } else { Event.AllServer.Add(@event); } }
static IntPtr BuildVTable(Callback.Run run, List <GCHandle> allocations) { var RunStub = (Callback.RunCall)Callback.RunStub; var SizeStub = (Callback.GetCallbackSizeBytes)Callback.SizeStub; allocations.Add(GCHandle.Alloc(run)); allocations.Add(GCHandle.Alloc(RunStub)); allocations.Add(GCHandle.Alloc(SizeStub)); var a = Marshal.GetFunctionPointerForDelegate <Callback.Run>(run); var b = Marshal.GetFunctionPointerForDelegate <Callback.RunCall>(RunStub); var c = Marshal.GetFunctionPointerForDelegate <Callback.GetCallbackSizeBytes>(SizeStub); var vt = Marshal.AllocHGlobal(IntPtr.Size * 3); if (Config.Os == OsType.Windows) { Marshal.WriteIntPtr(vt, IntPtr.Size * 0, b); Marshal.WriteIntPtr(vt, IntPtr.Size * 1, a); Marshal.WriteIntPtr(vt, IntPtr.Size * 2, c); } else { Marshal.WriteIntPtr(vt, IntPtr.Size * 0, a); Marshal.WriteIntPtr(vt, IntPtr.Size * 1, b); Marshal.WriteIntPtr(vt, IntPtr.Size * 2, c); } return(vt); }
static IntPtr BuildVTable(Callback.Run run, List <GCHandle> allocations) { var RunStub = (Callback.RunCall)Callback.RunStub; var SizeStub = (Callback.GetCallbackSizeBytes)Callback.SizeStub; allocations.Add(GCHandle.Alloc(run)); allocations.Add(GCHandle.Alloc(RunStub)); allocations.Add(GCHandle.Alloc(SizeStub)); var a = Marshal.GetFunctionPointerForDelegate <Callback.Run>(run); var b = Marshal.GetFunctionPointerForDelegate <Callback.RunCall>(RunStub); var c = Marshal.GetFunctionPointerForDelegate <Callback.GetCallbackSizeBytes>(SizeStub); var vt = Marshal.AllocHGlobal(IntPtr.Size * 3); // Windows switches the function positions #if PLATFORM_WIN Marshal.WriteIntPtr(vt, IntPtr.Size * 0, b); Marshal.WriteIntPtr(vt, IntPtr.Size * 1, a); Marshal.WriteIntPtr(vt, IntPtr.Size * 2, c); #else Marshal.WriteIntPtr(vt, IntPtr.Size * 0, a); Marshal.WriteIntPtr(vt, IntPtr.Size * 1, b); Marshal.WriteIntPtr(vt, IntPtr.Size * 2, c); #endif return(vt); }
internal static void Register(Callback.Run func, int size, int callbackId, bool gameserver) { var r = new Event(); r.vTablePtr = BuildVTable(func, r.Allocations); // // Create the callback object // var cb = new Callback(); cb.vTablePtr = r.vTablePtr; cb.CallbackFlags = gameserver ? (byte)0x02 : (byte)0; cb.CallbackId = callbackId; // // Pin the callback, so it doesn't get garbage collected and we can pass the pointer to native // r.PinnedCallback = GCHandle.Alloc(cb, GCHandleType.Pinned); // // Register the callback with Steam // SteamClient.RegisterCallback(r.PinnedCallback.AddrOfPinnedObject(), cb.CallbackId); r.IsAllocated = true; if (gameserver) { Event.AllServer.Add(r); } else { Event.AllClient.Add(r); } }