'GL.IssuePluginEvent(int)' is obsolete, so what's the newfangled way of using that function?

I’m trying to develop for a VR headset and the SDK is out of date, it only works on an old October build of Unity (2018.2.11). Anything more recent than that and my game is just a black screen.

Rather than continue developing on an old Unity version I’m trying to update the deprecated and obsolete functions the SDK was using. There’s only one class I haven’t updated, it uses the GL.IssuePluginEvent() function 4 times and prompts this warning in Unity:

‘GL.IssuePluginEvent(int)’ is obsolete: ‘IssuePluginEvent(eventID) is deprecated. Use IssuePluginEvent(callback, eventID) instead.’

Each of these functions only passes an int which seems to make them just plain nonfunctioning in newer versions of Unity (hence the black screen) so I think I need to update them to pass an IntPtr callback as well. Unfortunately the entire class doesn’t use any callback functions and IntPtr.Zero causes errors. Is there an obvious default choice for a callback function? How much of this code would I have to rewrite to get it to work?

Here is the code in question. In case it’s important I’m including the whole class, but only the first two functions are causing the obsolete warnings.

using UnityEngine;
using System;

public enum RenderEventType
{
    
    InitRenderThread = 0,
    Pause = 1,
    Resume = 2,
    LeftEyeEndFrame = 3,
    RightEyeEndFrame = 4,
    TimeWarp = 5,
    ResetVrModeParms = 6,
    ShutdownRenderThread = 7,
}

public static class SDKPluginEvent
{

    public static void Issue(RenderEventType eventType) {
    	GL.IssuePluginEvent(EncodeType((int)eventType));
    }

    public static void IssueWithData(RenderEventType eventType, int eventData) {
    	// Encode and send-two-bytes of data
    	GL.IssuePluginEvent(EncodeData((int)eventType, eventData, 0));

    	// Encode and send remaining two-bytes of data
    	GL.IssuePluginEvent(EncodeData((int)eventType, eventData, 1));

    	// Explicit event that uses the data
    	GL.IssuePluginEvent(EncodeType((int)eventType));
    }

    private const UInt32 IS_DATA_FLAG = 0x80000000;
    private const UInt32 DATA_POS_MASK = 0x40000000;
    private const int DATA_POS_SHIFT = 30;
    private const UInt32 EVENT_TYPE_MASK = 0x3E000000;
    private const int EVENT_TYPE_SHIFT = 25;
    private const UInt32 PAYLOAD_MASK = 0x0000FFFF;
    private const int PAYLOAD_SHIFT = 16;

    private static int EncodeType(int eventType) {
    	return (int)((UInt32)eventType & ~IS_DATA_FLAG); // make sure upper bit is not set
    }

    private static int EncodeData(int eventId, int eventData, int pos) {
    	UInt32 data = 0;
    	data |= IS_DATA_FLAG;
    	data |= (((UInt32)pos << DATA_POS_SHIFT) & DATA_POS_MASK);
    	data |= (((UInt32)eventId << EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK);
    	data |= (((UInt32)eventData >> (pos * PAYLOAD_SHIFT)) & PAYLOAD_MASK);

    	return (int)data;
    }

    private static int DecodeData(int eventData) {
    	UInt32 pos = (((UInt32)eventData & DATA_POS_MASK) >> DATA_POS_SHIFT);
    	UInt32 payload = (((UInt32)eventData & PAYLOAD_MASK) << (PAYLOAD_SHIFT * (int)pos));

	    return (int)payload;
    }
}

Well, have you checked the documentation of GL.IssuePluginEvent? The last sentence is:

See Native Plugin Interface for more details and an example.

So your native plugin should provide a method that actually returns the address of the callback method you want to call. You can call this native method from Unity by using an extern delcaration of that native method in C# which returns an IntPtr (the pointer to the native callback method). You just pass this IntPtr to the IssuePluginEvent method.