public static T Result <T>(SteamAPICall_t handle) where T : new() { var t = new T(); var size = Marshal.SizeOf(t); System.IntPtr unmanagedAddr = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(t, unmanagedAddr, true); bool failed; Steamworks.SteamUtils.GetAPICallResult(handle, unmanagedAddr, (int)size, CallbackIdentities.GetCallbackIdentity(typeof(T)), out failed); t = (T)Marshal.PtrToStructure(unmanagedAddr, typeof(T)); Marshal.FreeHGlobal(unmanagedAddr); unmanagedAddr = IntPtr.Zero; return(t); }
// Steamworks.NET Specific private void BuildCCallbackBase() { _vTable = new CCallbackBaseVTable { RunCallResult = OnRunCallResult, RunCallback = OnRunCallback, GetCallbackSizeBytes = OnGetCallbackSizeBytes }; _pVTable = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CCallbackBaseVTable))); Marshal.StructureToPtr(_vTable, _pVTable, false); _callbackBase = new CallbackBase { VFPtr = _pVTable, CallbackFlags = 0, Callback = CallbackIdentities.GetCallbackIdentity(typeof(T)) }; _pCCallbackBase = GCHandle.Alloc(_callbackBase, GCHandleType.Pinned); }
// Manual registration of the callback public void Register(DispatchDelegate func) { if (func == null) { throw new Exception("Callback function must not be null."); } if ((_callbackBase.CallbackFlags & CallbackBase.ECallbackFlagsRegistered) == CallbackBase.ECallbackFlagsRegistered) { Unregister(); } if (_gameServer) { SetGameserverFlag(); } Func = func; // ECallbackFlagsRegistered is set by SteamAPI_RegisterCallback. NativeMethods.SteamAPI_RegisterCallback(_pCCallbackBase.AddrOfPinnedObject(), CallbackIdentities.GetCallbackIdentity(typeof(T))); }