Skip to content

Commit cbba2e2

Browse files
committed
Support basic low level plugin interface
1 parent 2b44785 commit cbba2e2

5 files changed

Lines changed: 113 additions & 11 deletions

File tree

src/DllManipulator.cs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public static void LoadAll()
5353
{
5454
foreach (var nativeFunction in dll.functions)
5555
{
56-
LoadTargetFunction(nativeFunction);
56+
LoadTargetFunction(nativeFunction, false);
5757
}
5858
}
5959
}
@@ -76,6 +76,8 @@ public static void UnloadAll()
7676
{
7777
if (dll.handle != IntPtr.Zero)
7878
{
79+
LowLevelPluginManager.OnBeforeDllUnload(dll);
80+
7981
bool success = SysUnloadDll(dll.handle);
8082
dll.handle = IntPtr.Zero;
8183

@@ -198,7 +200,7 @@ private static DynamicMethod GetNativeFunctionMockMethod(MethodInfo nativeMethod
198200
_dlls.Add(dllName, dll);
199201
}
200202

201-
var nativeFunction = new NativeFunction(new NativeFunctionIdentity(nativeFunctionSymbol, dllName), dll);
203+
var nativeFunction = new NativeFunction(nativeFunctionSymbol, dll);
202204
dll.functions.Add(nativeFunction);
203205
var nativeFunctionIndex = _nativeFunctionsCount;
204206
AddNativeFunction(nativeFunction);
@@ -255,6 +257,7 @@ private static void GenerateNativeFunctionMockBody(ILGenerator il, ParameterInfo
255257
throw new InvalidOperationException("Thread safety with Lazy mode is not supported");
256258

257259
il.Emit(OpCodes.Dup);
260+
il.Emit(OpCodes.Ldc_I4_0); //ignoreLoadErrors -> false
258261
il.Emit(OpCodes.Call, Method_LoadTargetFunction.Value);
259262
}
260263

@@ -430,21 +433,27 @@ private static CustomAttributeBuilder CreateMarshalingAttributeBuilderFromAttrib
430433
/// To achieve thread safety calls to this method must be synchronized.
431434
/// Note: This method is being called by dynamically generated code. Be careful when changing its signature.
432435
/// </summary>
433-
private static void LoadTargetFunction(NativeFunction nativeFunction)
436+
internal static void LoadTargetFunction(NativeFunction nativeFunction, bool ignoreLoadError)
434437
{
435438
var dll = nativeFunction.containingDll;
436439
if (dll.handle == IntPtr.Zero)
437440
{
438441
dll.handle = SysLoadDll(dll.path);
439442
if (dll.handle == IntPtr.Zero)
440443
{
441-
dll.loadingError = true;
442-
Prop_EditorApplication_isPaused.Value?.SetValue(null, true);
443-
throw new NativeDllException($"Could not load DLL \"{dll.name}\" at path \"{dll.path}\".");
444+
if (!ignoreLoadError)
445+
{
446+
dll.loadingError = true;
447+
Prop_EditorApplication_isPaused.Value?.SetValue(null, true);
448+
throw new NativeDllException($"Could not load DLL \"{dll.name}\" at path \"{dll.path}\".");
449+
}
450+
451+
return;
444452
}
445453
else
446454
{
447455
dll.loadingError = false;
456+
LowLevelPluginManager.OnDllLoaded(dll);
448457
}
449458
}
450459

@@ -453,9 +462,14 @@ private static void LoadTargetFunction(NativeFunction nativeFunction)
453462
IntPtr funcPtr = SysGetDllProcAddress(dll.handle, nativeFunction.identity.symbol);
454463
if (funcPtr == IntPtr.Zero)
455464
{
456-
dll.symbolError = true;
457-
Prop_EditorApplication_isPaused.Value?.SetValue(null, true);
458-
throw new NativeDllException($"Could not get address of symbol \"{nativeFunction.identity.symbol}\" in DLL \"{dll.name}\" at path \"{dll.path}\".");
465+
if (!ignoreLoadError)
466+
{
467+
dll.symbolError = true;
468+
Prop_EditorApplication_isPaused.Value?.SetValue(null, true);
469+
throw new NativeDllException($"Could not get address of symbol \"{nativeFunction.identity.symbol}\" in DLL \"{dll.name}\" at path \"{dll.path}\".");
470+
}
471+
472+
return;
459473
}
460474
else
461475
{

src/DllManipulatorScript.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ private void OnEnable()
7575
}
7676
}
7777

78+
LowLevelPluginManager.Initialize();
79+
7880
if (DllManipulator.Options.loadingMode == DllLoadingMode.Preload)
7981
DllManipulator.LoadAll();
8082

src/LowLevelPluginManager.cs

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Reflection;
5+
using System.Reflection.Emit;
6+
using System.Runtime.InteropServices;
7+
using System.Runtime.CompilerServices;
8+
using System.Threading;
9+
using System.IO;
10+
using UnityEngine;
11+
12+
namespace UnityNativeTool.Internal
13+
{
14+
[DisableMocking]
15+
class LowLevelPluginManager
16+
{
17+
private static IntPtr _unityInterfacePtr = IntPtr.Zero;
18+
public static void Initialize()
19+
{
20+
try
21+
{
22+
_unityInterfacePtr = GetUnityInterfacesPtr();
23+
if (_unityInterfacePtr == IntPtr.Zero)
24+
throw new Exception($"{nameof(GetUnityInterfacesPtr)} returned null");
25+
}
26+
catch(DllNotFoundException ex)
27+
{
28+
Debug.Log(ex);
29+
}
30+
31+
Debug.Log("Initialize()");
32+
}
33+
34+
public static void OnDllLoaded(NativeDll dll)
35+
{
36+
Debug.Log("OnDllLoaded() " + _unityInterfacePtr);
37+
38+
if (_unityInterfacePtr == IntPtr.Zero)
39+
return;
40+
41+
var unityPluginLoadFunc = new NativeFunction("UnityPluginLoad", dll) {
42+
delegateType = typeof(UnityPluginLoadDel)
43+
};
44+
45+
DllManipulator.LoadTargetFunction(unityPluginLoadFunc, true);
46+
if (unityPluginLoadFunc.@delegate != null)
47+
{
48+
((UnityPluginLoadDel)unityPluginLoadFunc.@delegate)(_unityInterfacePtr);
49+
Debug.Log("Called UnityPluginLoad");
50+
}
51+
}
52+
53+
public static void OnBeforeDllUnload(NativeDll dll)
54+
{
55+
var unityPluginUnloadFunc = new NativeFunction("UnityPluginUnload", dll) {
56+
delegateType = typeof(UnityPluginUnloadDel)
57+
};
58+
59+
DllManipulator.LoadTargetFunction(unityPluginUnloadFunc, true);
60+
if (unityPluginUnloadFunc.@delegate != null)
61+
{
62+
Debug.Log("Called UnityPluginUnload");
63+
}
64+
}
65+
66+
delegate void UnityPluginLoadDel(IntPtr unityInterfaces);
67+
delegate void UnityPluginUnloadDel();
68+
69+
[DllImport("StubLluiPlugin")]
70+
private static extern IntPtr GetUnityInterfacesPtr();
71+
}
72+
}

src/NativeFunction.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,9 @@ internal class NativeFunction
3838
public Type delegateType = null;
3939
public int index = -1;
4040

41-
public NativeFunction(NativeFunctionIdentity identity, NativeDll containingDll)
41+
public NativeFunction(string symbol, NativeDll containingDll)
4242
{
43-
this.identity = identity;
43+
this.identity = new NativeFunctionIdentity(symbol, containingDll.name);
4444
this.containingDll = containingDll;
4545
}
4646
}

stubLluiPlugin/main.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include <stdio.h>
2+
#include "IUnityInterface.h"
3+
4+
static IUnityInterfaces* s_IUnityInterfaces = NULL;
5+
6+
UNITY_INTERFACE_EXPORT IUnityInterfaces* UNITY_INTERFACE_API GetUnityInterfacesPtr()
7+
{
8+
return s_IUnityInterfaces;
9+
}
10+
11+
UNITY_INTERFACE_EXPORT void UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces* unityInterfaces)
12+
{
13+
s_IUnityInterfaces = unityInterfaces;
14+
}

0 commit comments

Comments
 (0)