public static void OnBeforeDllUnload(NativeDll dll)
        {
            var unityPluginUnloadFunc = new NativeFunction("UnityPluginUnload", dll)
            {
                delegateType = typeof(UnityPluginUnloadDel)
            };

            DllManipulator.LoadTargetFunction(unityPluginUnloadFunc, true);
            if (unityPluginUnloadFunc.@delegate != null)
            {
                ((UnityPluginUnloadDel)unityPluginUnloadFunc.@delegate)();
            }
        }
Example #2
0
        /// <summary>
        /// Creates and registers new DynamicMethod that mocks <paramref name="nativeMethod"/> and itself calls dynamically loaded function from DLL.
        /// </summary>
        private static DynamicMethod GetNativeFunctionMockMethod(MethodInfo nativeMethod)
        {
            if (!_nativeFunctionMocks.TryGetValue(nativeMethod, out var mockedDynamicMethod))
            {
                var    dllImportAttr = nativeMethod.GetCustomAttribute <DllImportAttribute>();
                var    dllName       = dllImportAttr.Value;
                string dllPath;
                var    nativeFunctionSymbol = dllImportAttr.EntryPoint;

                if (_dlls.TryGetValue(dllName, out var dll))
                {
                    dllPath = dll.path;
                }
                else
                {
                    dllPath = ApplyDirectoryPathMacros(Options.dllPathPattern).Replace(DLL_PATH_PATTERN_DLL_NAME_MACRO, dllName);
                    dll     = new NativeDll(dllName, dllPath);
                    _dlls.Add(dllName, dll);
                }

                var nativeFunction = new NativeFunction(nativeFunctionSymbol, dll);
                dll.functions.Add(nativeFunction);
                var nativeFunctionIndex = _mockedNativeFunctions.Count;
                _mockedNativeFunctions.Add(nativeFunction);

                var parameters            = nativeMethod.GetParameters();
                var parameterTypes        = parameters.Select(x => x.ParameterType).ToArray();
                var nativeMethodSignature = new NativeFunctionSignature(nativeMethod, dllImportAttr.CallingConvention,
                                                                        dllImportAttr.BestFitMapping, dllImportAttr.CharSet, dllImportAttr.SetLastError, dllImportAttr.ThrowOnUnmappableChar);
                if (!_delegateTypesForNativeFunctionSignatures.TryGetValue(nativeMethodSignature, out nativeFunction.delegateType))
                {
                    nativeFunction.delegateType = CreateDelegateTypeForNativeFunctionSignature(nativeMethodSignature, nativeMethod.Name);
                    _delegateTypesForNativeFunctionSignatures.Add(nativeMethodSignature, nativeFunction.delegateType);
                }
                var targetDelegateInvokeMethod = nativeFunction.delegateType.GetMethod("Invoke", BindingFlags.Instance | BindingFlags.Public);

                mockedDynamicMethod = new DynamicMethod(dllName + ":::" + nativeFunctionSymbol, nativeMethod.ReturnType, parameterTypes, typeof(DllManipulator));
                mockedDynamicMethod.DefineParameter(0, nativeMethod.ReturnParameter.Attributes, null);
                for (int i = 0; i < parameters.Length; i++)
                {
                    mockedDynamicMethod.DefineParameter(i + 1, parameters[i].Attributes, null);
                }

                GenerateNativeFunctionMockBody(mockedDynamicMethod.GetILGenerator(), parameters, targetDelegateInvokeMethod, nativeFunctionIndex);

                _antiGcRefHolder.AddLast(nativeFunction);
                _antiGcRefHolder.AddLast(mockedDynamicMethod);
            }

            return(mockedDynamicMethod);
        }
        public static void OnDllLoaded(NativeDll dll)
        {
            if (_unityInterfacePtr == IntPtr.Zero)
            {
                return;
            }

            var unityPluginLoadFunc = new NativeFunction("UnityPluginLoad", dll)
            {
                delegateType = typeof(UnityPluginLoadDel)
            };

            DllManipulator.LoadTargetFunction(unityPluginLoadFunc, true);
            if (unityPluginLoadFunc.@delegate != null)
            {
                ((UnityPluginLoadDel)unityPluginLoadFunc.@delegate)(_unityInterfacePtr);
            }
        }
Example #4
0
        private static void InvokeCustomTriggers(List <MethodInfo> triggers, NativeDll dll)
        {
            if (triggers == null)
            {
                return;
            }

            foreach (var triggerMethod in triggers)
            {
                if (triggerMethod.GetParameters().Length == 1)
                {
                    triggerMethod.Invoke(null, new object[] { dll });
                }
                else
                {
                    triggerMethod.Invoke(null, Array.Empty <object>());
                }
            }
        }
        public static void OnDllLoaded(NativeDll dll)
        {
            if (_triedLoadingStubPlugin && _unityInterfacePtr == IntPtr.Zero)
            {
                return;
            }

            var unityPluginLoadFunc = new NativeFunction("UnityPluginLoad", dll)
            {
                delegateType = typeof(UnityPluginLoadDel)
            };

            DllManipulator.LoadTargetFunction(unityPluginLoadFunc, true);
            if (unityPluginLoadFunc.@delegate == null)
            {
                return;
            }

            if (!_triedLoadingStubPlugin)
            {
                try
                {
                    _unityInterfacePtr = GetUnityInterfacesPtr();
                    if (_unityInterfacePtr == IntPtr.Zero)
                    {
                        throw new Exception($"{nameof(GetUnityInterfacesPtr)} returned null");
                    }
                }
                catch (DllNotFoundException)
                {
                    Debug.LogWarning("StubLluiPlugin not found. UnityPluginLoad and UnityPluginUnload callbacks won't fire. If you didn't install UnityNativeTool from .unitypackage or it didn't contain the compiled plugin, you'll need to compile it manually. You may also comment out this warning if you don't care about these callbacks.");
                }
                finally
                {
                    _triedLoadingStubPlugin = true;
                }
            }

            if (_unityInterfacePtr != IntPtr.Zero)
            {
                ((UnityPluginLoadDel)unityPluginLoadFunc.@delegate)(_unityInterfacePtr);
            }
        }
Example #6
0
 public NativeFunction(string symbol, NativeDll containingDll)
 {
     this.identity      = new NativeFunctionIdentity(symbol, containingDll.name);
     this.containingDll = containingDll;
 }
Example #7
0
        private static void InvokeCustomTriggers(List <Tuple <MethodInfo, bool> > triggers, NativeDll dll)
        {
            if (triggers == null)
            {
                return;
            }

            foreach (var(methodInfo, useMainThreadQueue) in triggers)
            {
                object[] args;

                // Determine args for method
                if (methodInfo.GetParameters().Length == 2)
                {
                    args = new object[] { dll, _unityMainThreadId }
                }
                ;
                else if (methodInfo.GetParameters().Length == 1)
                {
                    args = new object[] { dll }
                }
                ;
                else
                {
                    args = Array.Empty <object>();
                }

                // Execute now or queue to the main thread
                if (useMainThreadQueue && Thread.CurrentThread.ManagedThreadId != _unityMainThreadId)
                {
                    DllManipulatorScript.MainThreadTriggerQueue.Enqueue(() => methodInfo.Invoke(null, args));
                }
                else
                {
                    methodInfo.Invoke(null, args);
                }
            }
        }