Accessing the Low-level Native Plugin Interface in DLL that isn't actually loaded as a native plugin

In my current project I have split the codebase in usual managed C# scripts and native C++ code. Instead of adding the native DLL as an asset (aka native plugin) I load it manually via C# using interop calls to LoadLibrary (not even using DllIImport to enable hot reloading during debugging).

This works just fine for the time being, however I wanted to hook into the renderer and saw this entry in the documentation. Of course I can’t just export the UnityPluginLoad method since my particular DLL is loaded manually hence the UnityPluginLoad isn’t called in the first place.

My question is basically, how can I manually call that method with the appropriate interfaces in the first place? Here are my current thoughts on the topic:

  1. Maybe the managed Unity code exposes a method to get access to the necessary IUnityInterfaces* pointer that I can manually pass to my LoadLibrary’ed DLL which mimicks an automated invocation of the DLL from Unitys end.
  2. Alternatively, I could create an actual native plugin that acts as a proxy with the following code:
#include "IUnityInterface.h"
#include "IUnityGraphics.h"
   
static IUnityInterfaces* UnityInterfaces = nullptr;  

extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
    UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
    UnityInterfaces = unityInterfaces;
}

extern "C" IUnityInterfaces* __declspec(dllexport) GetInterfaces()
{
    return UnityInterfaces;
}

In my C# script I could call GetInterfaces and supply my actual native code with the returned pointer assuming it won’t be arbitrarily invalidated. Assuming this will work, I would be able to write the actual renderer code in my manually loaded DLL, right?

Short update: the second approach works right now. It might not be the easiest, but it does its job for the time being. ¯_(ツ)_/¯

1 Like

Did you ever find a better solution, or is this still the state of the art solution ?

We had hit this same issue too, and the only solution was a proxy dll, but would be a lot nicer if there was just a C# function we could call to get the pointer!