C# 동적 교체 방법 사용
견본 using UnityEngine;
using System;
using System.Collections;
using System.Reflection;
public class ReplaceMethod1 : MonoBehaviour
{
static void ExchangeFunctionPointer(MethodInfo method0, MethodInfo method1)
{
unsafe
{
var functionPointer0 = method0.MethodHandle.Value.ToPointer();
var functionPointer1 = method1.MethodHandle.Value.ToPointer();
var tmpPointer = *((int*)new IntPtr(((int*)functionPointer0 + 1)).ToPointer());
*((int*)new IntPtr(((int*)functionPointer0 + 1)).ToPointer()) = *((int*)new IntPtr(((int*)functionPointer1 + 1)).ToPointer());
*((int*)new IntPtr(((int*)functionPointer1 + 1)).ToPointer()) = tmpPointer;
}
}
void Awake()
{
MethodInfo onGuiMethod = this.GetType().GetMethod("OnGUI", BindingFlags.NonPublic | BindingFlags.Instance);
MethodInfo onGuiV2Method = this.GetType().GetMethod("OnGUIv2", BindingFlags.NonPublic | BindingFlags.Instance);
ExchangeFunctionPointer(onGuiMethod, onGuiV2Method);
}
void OnGUI()
{
if (GUILayout.Button("This is OnGUIv1"))
{
}
}
void OnGUIv2()
{
if (GUILayout.Button("This is OnGUIv2"))
{
}
}
}
실행 결과
OnGUI 대신 OnGUIv2가 호출되었습니다.
적당한 해설
하고 있는 일
1. Awake의 반사로 OnGUI, OnGUIv2 방법을 얻어 Exchange Function Pointer 방법에 두 가지 투입
2. Exchange Function Pointer 메서드에서 실제 처리된 함수 포인터를 다음으로 대체
3. 끝
바늘이 머무르는 관계에서 아마도 unsafe일 것이다.
이 예에서 두 가지 방법의 처리는 교체된 것이지만 이것은 절대적인 것이 아니라 지침을 공유할 수도 있다.
iOS 실기에서도 작동돼 충격적이었다.
단, 한 번에 실제 호출하는 방법도 변경할 수 없다
치명상이야...using UnityEngine;
using System;
using System.Collections;
using System.Reflection;
public class ReplaceMethod1 : MonoBehaviour
{
static void ExchangeFunctionPointer(MethodInfo method0, MethodInfo method1)
{
unsafe
{
var functionPointer0 = method0.MethodHandle.Value.ToPointer();
var functionPointer1 = method1.MethodHandle.Value.ToPointer();
var tmpPointer = *((int*)new IntPtr(((int*)functionPointer0 + 1)).ToPointer());
*((int*)new IntPtr(((int*)functionPointer0 + 1)).ToPointer()) = *((int*)new IntPtr(((int*)functionPointer1 + 1)).ToPointer());
*((int*)new IntPtr(((int*)functionPointer1 + 1)).ToPointer()) = tmpPointer;
}
}
void OnGUI()
{
if (GUILayout.Button("This is OnGUIv1"))
{
MethodInfo onGuiMethod = this.GetType().GetMethod("OnGUI", BindingFlags.NonPublic | BindingFlags.Instance);
MethodInfo onGuiV2Method = this.GetType().GetMethod("OnGUIv2", BindingFlags.NonPublic | BindingFlags.Instance);
ExchangeFunctionPointer(onGuiMethod, onGuiV2Method); }
}
void OnGUIv2()
{
if (GUILayout.Button("This is OnGUIv2"))
{
MethodInfo onGuiMethod = this.GetType().GetMethod("OnGUI", BindingFlags.NonPublic | BindingFlags.Instance);
MethodInfo onGuiV2Method = this.GetType().GetMethod("OnGUIv2", BindingFlags.NonPublic | BindingFlags.Instance);
ExchangeFunctionPointer(onGuiMethod, onGuiV2Method); }
}
}
원래 이렇게 하려고 했는데 어쨌든 로드하는 방법이 나중에 지침을 붙여도 의미가 없나요?
Debug.애플 회사.Register LogCallback 이외의 방법으로 연결을 하는 용도 등 #if UNITY_EDITOR
using UnityEditor;
using System;
using System.Collections;
using System.Reflection;
[InitializeOnLoad]
public class ReplaceMethod2
{
static ReplaceMethod2()
{
MethodInfo logMethod = typeof(Debug).GetMethod("Log", new System.Type[] { typeof(object) });
MethodInfo logWarningMethod = typeof(Debug).GetMethod("LogWarning", new System.Type[] { typeof(object) });
ExchangeFunctionPointer(logMethod, logWarningMethod);
Debug.LogWarning("this is Warning");
Debug.Log("this is Log");
}
static void ExchangeFunctionPointer(MethodInfo method0, MethodInfo method1)
{
unsafe
{
var functionPointer0 = method0.MethodHandle.Value.ToPointer();
var functionPointer1 = method1.MethodHandle.Value.ToPointer();
var tmpPointer = *((int*)new IntPtr(((int*)functionPointer0 + 1)).ToPointer());
*((int*)new IntPtr(((int*)functionPointer0 + 1)).ToPointer()) = *((int*)new IntPtr(((int*)functionPointer1 + 1)).ToPointer());
*((int*)new IntPtr(((int*)functionPointer1 + 1)).ToPointer()) = tmpPointer;
}
}
}
#endif
지상 Debug.Log 및 Debug워닝을 교체해보세요.
Reference
이 문제에 관하여(C# 동적 교체 방법 사용), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/satanabe1@github/items/08f7994d26840e14362d
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
using UnityEngine;
using System;
using System.Collections;
using System.Reflection;
public class ReplaceMethod1 : MonoBehaviour
{
static void ExchangeFunctionPointer(MethodInfo method0, MethodInfo method1)
{
unsafe
{
var functionPointer0 = method0.MethodHandle.Value.ToPointer();
var functionPointer1 = method1.MethodHandle.Value.ToPointer();
var tmpPointer = *((int*)new IntPtr(((int*)functionPointer0 + 1)).ToPointer());
*((int*)new IntPtr(((int*)functionPointer0 + 1)).ToPointer()) = *((int*)new IntPtr(((int*)functionPointer1 + 1)).ToPointer());
*((int*)new IntPtr(((int*)functionPointer1 + 1)).ToPointer()) = tmpPointer;
}
}
void Awake()
{
MethodInfo onGuiMethod = this.GetType().GetMethod("OnGUI", BindingFlags.NonPublic | BindingFlags.Instance);
MethodInfo onGuiV2Method = this.GetType().GetMethod("OnGUIv2", BindingFlags.NonPublic | BindingFlags.Instance);
ExchangeFunctionPointer(onGuiMethod, onGuiV2Method);
}
void OnGUI()
{
if (GUILayout.Button("This is OnGUIv1"))
{
}
}
void OnGUIv2()
{
if (GUILayout.Button("This is OnGUIv2"))
{
}
}
}
치명상이야...
using UnityEngine;
using System;
using System.Collections;
using System.Reflection;
public class ReplaceMethod1 : MonoBehaviour
{
static void ExchangeFunctionPointer(MethodInfo method0, MethodInfo method1)
{
unsafe
{
var functionPointer0 = method0.MethodHandle.Value.ToPointer();
var functionPointer1 = method1.MethodHandle.Value.ToPointer();
var tmpPointer = *((int*)new IntPtr(((int*)functionPointer0 + 1)).ToPointer());
*((int*)new IntPtr(((int*)functionPointer0 + 1)).ToPointer()) = *((int*)new IntPtr(((int*)functionPointer1 + 1)).ToPointer());
*((int*)new IntPtr(((int*)functionPointer1 + 1)).ToPointer()) = tmpPointer;
}
}
void OnGUI()
{
if (GUILayout.Button("This is OnGUIv1"))
{
MethodInfo onGuiMethod = this.GetType().GetMethod("OnGUI", BindingFlags.NonPublic | BindingFlags.Instance);
MethodInfo onGuiV2Method = this.GetType().GetMethod("OnGUIv2", BindingFlags.NonPublic | BindingFlags.Instance);
ExchangeFunctionPointer(onGuiMethod, onGuiV2Method); }
}
void OnGUIv2()
{
if (GUILayout.Button("This is OnGUIv2"))
{
MethodInfo onGuiMethod = this.GetType().GetMethod("OnGUI", BindingFlags.NonPublic | BindingFlags.Instance);
MethodInfo onGuiV2Method = this.GetType().GetMethod("OnGUIv2", BindingFlags.NonPublic | BindingFlags.Instance);
ExchangeFunctionPointer(onGuiMethod, onGuiV2Method); }
}
}
원래 이렇게 하려고 했는데 어쨌든 로드하는 방법이 나중에 지침을 붙여도 의미가 없나요?Debug.애플 회사.Register LogCallback 이외의 방법으로 연결을 하는 용도 등 #if UNITY_EDITOR
using UnityEditor;
using System;
using System.Collections;
using System.Reflection;
[InitializeOnLoad]
public class ReplaceMethod2
{
static ReplaceMethod2()
{
MethodInfo logMethod = typeof(Debug).GetMethod("Log", new System.Type[] { typeof(object) });
MethodInfo logWarningMethod = typeof(Debug).GetMethod("LogWarning", new System.Type[] { typeof(object) });
ExchangeFunctionPointer(logMethod, logWarningMethod);
Debug.LogWarning("this is Warning");
Debug.Log("this is Log");
}
static void ExchangeFunctionPointer(MethodInfo method0, MethodInfo method1)
{
unsafe
{
var functionPointer0 = method0.MethodHandle.Value.ToPointer();
var functionPointer1 = method1.MethodHandle.Value.ToPointer();
var tmpPointer = *((int*)new IntPtr(((int*)functionPointer0 + 1)).ToPointer());
*((int*)new IntPtr(((int*)functionPointer0 + 1)).ToPointer()) = *((int*)new IntPtr(((int*)functionPointer1 + 1)).ToPointer());
*((int*)new IntPtr(((int*)functionPointer1 + 1)).ToPointer()) = tmpPointer;
}
}
}
#endif
지상 Debug.Log 및 Debug워닝을 교체해보세요.
Reference
이 문제에 관하여(C# 동적 교체 방법 사용), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/satanabe1@github/items/08f7994d26840e14362d
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
#if UNITY_EDITOR
using UnityEditor;
using System;
using System.Collections;
using System.Reflection;
[InitializeOnLoad]
public class ReplaceMethod2
{
static ReplaceMethod2()
{
MethodInfo logMethod = typeof(Debug).GetMethod("Log", new System.Type[] { typeof(object) });
MethodInfo logWarningMethod = typeof(Debug).GetMethod("LogWarning", new System.Type[] { typeof(object) });
ExchangeFunctionPointer(logMethod, logWarningMethod);
Debug.LogWarning("this is Warning");
Debug.Log("this is Log");
}
static void ExchangeFunctionPointer(MethodInfo method0, MethodInfo method1)
{
unsafe
{
var functionPointer0 = method0.MethodHandle.Value.ToPointer();
var functionPointer1 = method1.MethodHandle.Value.ToPointer();
var tmpPointer = *((int*)new IntPtr(((int*)functionPointer0 + 1)).ToPointer());
*((int*)new IntPtr(((int*)functionPointer0 + 1)).ToPointer()) = *((int*)new IntPtr(((int*)functionPointer1 + 1)).ToPointer());
*((int*)new IntPtr(((int*)functionPointer1 + 1)).ToPointer()) = tmpPointer;
}
}
}
#endif
Reference
이 문제에 관하여(C# 동적 교체 방법 사용), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/satanabe1@github/items/08f7994d26840e14362d텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)