Giter Club home page Giter Club logo

Comments (12)

pardeike avatar pardeike commented on May 12, 2024 1

The method signature of a transpiler is:

static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)

so defining a Transpiler that returns void will certainly not work. Your typical transpiler looks like these examples:

static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
	bool previousPopInstruction = false;
	foreach (var instruction in instructions)
	{
		if (previousPopInstruction == false && instruction.opcode == OpCodes.Pop)
		{
			previousPopInstruction = true;
			yield return instruction;
		}
		else if (previousPopInstruction && instruction.opcode == OpCodes.Ldsfld && (FieldInfo)instruction.operand == writeCellContentsField)
		{
			yield return new CodeInstruction(OpCodes.Ldloc_0);
			yield return new CodeInstruction(OpCodes.Call, debugGridMethod);
			yield return instruction;
		}
		else
		{
			yield return instruction;
			previousPopInstruction = false;
		}
	}
}

or with the build-in method replacer:

static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
{
	return Transpilers.MethodReplacer(instructions,
		AccessTools.Method(typeof(SOURCETYPE), "SOURCEMETHODNAME"),
		AccessTools.Method(typeof(DESTINATIONTYPE), "DESTINATIONMETHODNAME")
	);
}

or you can simply add a Prefix instead that returns false so that the original is not called:

static bool Prefix(...)
{
	// your code here
	return false;
}

from harmony.

pardeike avatar pardeike commented on May 12, 2024 1

Make sure you follow the documentation on the wiki:
https://github.com/pardeike/Harmony/wiki/Patching

from harmony.

pardeike avatar pardeike commented on May 12, 2024 1

Make sure that the name of the parameter "velocityX" matches exactly the name of the parameter in the original method (You can also try to omit it). Also: use

HarmonyInstance.DEBUG = true;

before you run PatchAll and Harmony will write out a debug log to your Desktop. That will help you find out which IL code fails and will certainly help you debug this issue.

from harmony.

alicint avatar alicint commented on May 12, 2024

stack trace:

05-09 14:06:45.059 I/MonoDroid(26534): System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.NullReferenceException: Object reference not set to an instance of an object.
05-09 14:06:45.059 I/MonoDroid(26534):   at Harmony.CodeTranspiler.ConvertInstructions (System.Type type, System.Collections.IEnumerable enumerable) [0x00000] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 14:06:45.059 I/MonoDroid(26534):   at Harmony.CodeTranspiler.ConvertInstructions (System.Reflection.MethodInfo transpiler, System.Collections.IEnumerable enumerable) [0x0004e] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 14:06:45.059 I/MonoDroid(26534):   at Harmony.CodeTranspiler+<>c__DisplayClass6_0.<GetResult>b__0 (System.Reflection.MethodInfo transpiler) [0x0000d] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 14:06:45.060 I/MonoDroid(26534):   at System.Collections.Generic.List`1[T].ForEach (System.Action`1[T] action) [0x00035] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/referencesource/mscorlib/system/collections/generic/list.cs:564 
05-09 14:06:45.060 I/MonoDroid(26534):   at Harmony.CodeTranspiler.GetResult (System.Reflection.Emit.ILGenerator generator, System.Reflection.MethodBase method) [0x00020] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 14:06:45.060 I/MonoDroid(26534):   at Harmony.ILCopying.MethodBodyReader.FinalizeILCodes (System.Collections.Generic.List`1[T] transpilers, System.Reflection.Emit.Label endLabel) [0x00050] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 14:06:45.060 I/MonoDroid(26534):   at Harmony.ILCopying.MethodCopier.Emit (System.Reflection.Emit.Label endLabel) [0x00000] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 14:06:45.060 I/MonoDroid(26534):   at Harmony.MethodPatcher.CreatePatchedMethod (System.Reflection.MethodBase original, System.Collections.Generic.List`1[T] prefixes, System.Collections.Generic.List`1[T] postfixes, System.Collections.Generic.List`1[T] transpilers) [0x00131] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 14:06:45.060 I/MonoDroid(26534):   at Harmony.PatchFunctions.UpdateWrapper (System.Reflection.MethodBase original, Harmony.PatchInfo patchInfo) [0x00027] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 14:06:45.060 I/MonoDroid(26534):   at Harmony.PatchProcessor.Patch () [0x00066] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 14:06:45.060 I/MonoDroid(26534):   at Harmony.HarmonyInstance.<PatchAll>b__6_0 (System.Type type) [0x00022] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 14:06:45.060 I/MonoDroid(26534):   at Harmony.CollectionExtensions.Do[T] (System.Collections.Generic.IEnumerable`1[T] sequence, System.Action`1[T] action) [0x00015] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 14:06:45.060 I/MonoDroid(26534):   at Harmony.HarmonyInstance.PatchAll (System.Reflection.Assembly assembly) [0x00006] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 14:06:45.060 I/MonoDroid(26534):   at XamAndroid.XamApplication..ctor (System.IntPtr javaReference, Android.Runtime.JniHandleOwnership transfer) [0x00015] in D:\temp\xamarin\XamAndroid\XamAndroid\XamApplication.cs:24 
05-09 14:06:45.060 I/MonoDroid(26534):   at (wrapper managed-to-native) System.Reflection.MonoCMethod:InternalInvoke (System.Reflection.MonoCMethod,object,object[],System.Exception&)
05-09 14:06:45.060 I/MonoDroid(26534):   at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00002] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:661 
05-09 14:06:45.060 I/MonoDroid(26534):    --- End of inner exception stack trace ---
05-09 14:06:45.060 I/MonoDroid(26534):   at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00016] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:667 
05-09 14:06:45.060 I/MonoDroid(26534):   at System.Reflection.MonoCMethod.DoInvoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00089] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:652 
05-09 14:06:45.060 I/MonoDroid(26534):   at System.Reflection.MonoCMethod.Invoke (System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:680 
05-09 14:06:45.060 I/MonoDroid(26534):   at System.Reflection.ConstructorInfo.Invoke (System.Object[] parameters) [0x00000] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/corlib/System.Reflection/ConstructorInfo.cs:62 
05-09 14:06:45.061 I/MonoDroid(26534):   at Java.Interop.TypeManager.CreateProxy (System.Type type, System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer) [0x00059] in /Users/builder/data/lanes/4009/3a62f1ea/source/xamarin-android/src/Mono.Android/Java.Interop/TypeManager.cs:308 
05-09 14:06:45.062 I/MonoDroid(26534):   at Java.Interop.TypeManager.CreateInstance (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer, System.Type targetType) [0x00138] in /Users/builder/data/lanes/4009/3a62f1ea/source/xamarin-android/src/Mono.Android/Java.Interop/TypeManager.cs:282 
05-09 14:06:45.062 I/MonoDroid(26534):   at Java.Lang.Object.GetObject (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer, System.Type type) [0x000e5] in /Users/builder/data/lanes/4009/3a62f1ea/source/xamarin-android/src/Mono.Android/Java.Lang/Object.cs:459 
05-09 14:06:45.062 I/MonoDroid(26534):   at Java.Lang.Object._GetObject[T] (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer) [0x0001a] in /Users/builder/data/lanes/4009/3a62f1ea/source/xamarin-android/src/Mono.Android/Java.Lang/Object.cs:430 
05-09 14:06:45.062 I/MonoDroid(26534):   at Java.Lang.Object.GetObject[T] (System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer) [0x00000] in /Users/builder/data/lanes/4009/3a62f1ea/source/xamarin-android/src/Mono.Android/Java.Lang/Object.cs:422 
05-09 14:06:45.062 I/MonoDroid(26534):   at Java.Lang.Object.GetObject[T] (System.IntPtr jnienv, System.IntPtr handle, Android.Runtime.JniHandleOwnership transfer) [0x00006] in /Users/builder/data/lanes/4009/3a62f1ea/source/xamarin-android/src/Mono.Android/Java.Lang/Object.cs:416 
05-09 14:06:45.062 I/MonoDroid(26534):   at Android.App.Application.n_OnCreate (System.IntPtr jnienv, System.IntPtr native__this) [0x00000] in /Users/builder/data/lanes/4009/3a62f1ea/source/monodroid/src/Mono.Android/platforms/android-22/src/generated/Android.App.Application.cs:557 
05-09 14:06:45.062 I/MonoDroid(26534):   at (wrapper dynamic-method) System.Object:2b62d1e8-408b-4d4d-851f-d06c6a5331e0 (intptr,intptr)
An unhandled exception occured.

from harmony.

pardeike avatar pardeike commented on May 12, 2024

Can you post the code of your patch methods? I guess you are using a Transpiler but it isn't really clear from the stacktrace.

from harmony.

alicint avatar alicint commented on May 12, 2024

yes I'm trying to use a transpiler to replace a method implementation with a method with empty body.

this is I think the highest entry point to a Xamarin.Android Application:


    [Application]
    public class XamApplication : Application
    {
        public XamApplication(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
        {
            var harmony = HarmonyInstance.Create("com.github.harmony.rimworld.mod.example");
            harmony.PatchAll(Assembly.GetExecutingAssembly());
        }

        public override void OnCreate()
        {
            base.OnCreate();
            //app init ...
        }
    }

this is my android activity which has a class for harmony patch:

    [Activity(Label = "XamAndroid", MainLauncher = true, Icon = "@drawable/icon")]
    public class MainActivity : Activity, View.IOnClickListener, View.IOnTouchListener
    {
        private HorizontalScrollView hsv;

        [HarmonyPatch(typeof(HorizontalScrollView), "Fling", new Type[] {typeof(int)})]
        public class Patch
        {
            [HarmonyTranspiler]
            public static void Transpiler(int i)
            {
                System.Diagnostics.Debug.WriteLine("callled");
            }
        }
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            SetContentView(Resource.Layout.Main);
            hsv = FindViewById<HorizontalScrollView>(Resource.Id.sv);
        }
    }

I tried manual patching as well but got the same error

from harmony.

alicint avatar alicint commented on May 12, 2024

oh thanks then Its not as easy as I thought, but its good that I still can use Perfix to achieve what I want, I'll give it a go and report back.

btw, I think the library could give a more usefull error message in case the method signature is incorrect, rather than a nullref exception.

from harmony.

alicint avatar alicint commented on May 12, 2024

ok I used Prefix() method and got this error instead:


05-09 15:22:14.785 E/mono    (30705): Unhandled Exception:
05-09 15:22:14.785 E/mono    (30705): System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidProgramException: Invalid IL code in (wrapper dynamic-method) Android.Widget.HorizontalScrollView:Fling_Patch1 (object,int): IL_003c: endfinally
05-09 15:22:14.785 E/mono    (30705): 
05-09 15:22:14.785 E/mono    (30705): 
05-09 15:22:14.785 E/mono    (30705):   at (wrapper managed-to-native) System.RuntimeMethodHandle:GetFunctionPointer (intptr)
05-09 15:22:14.785 E/mono    (30705):   at System.RuntimeMethodHandle.GetFunctionPointer () [0x00000] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/corlib/System/RuntimeMethodHandle.cs:87 
05-09 15:22:14.785 E/mono    (30705):   at Harmony.ILCopying.Memory.GetMethodStart (System.Reflection.MethodBase method) [0x00007] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 15:22:14.785 E/mono    (30705):   at Harmony.PatchFunctions.UpdateWrapper (System.Reflection.MethodBase original, Harmony.PatchInfo patchInfo) [0x0004b] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 15:22:14.785 E/mono    (30705):   at Harmony.PatchProcessor.Patch () [0x00066] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 15:22:14.785 E/mono    (30705):   at Harmony.HarmonyInstance.<PatchAll>b__6_0 (System.Type type) [0x00022] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 15:22:14.785 E/mono    (30705):   at Harmony.CollectionExtensions.Do[T] (System.Collections.Generic.IEnumerable`1[T] sequence, System.Action`1[T] action) [0x00015] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 15:22:14.785 E/mono    (30705):   at Harmony.HarmonyInstance.PatchAll (System.Reflection.Assembly assembly) [0x00006] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 15:22:14.785 E/mono    (30705):   at XamAndroid.XamApplication..ctor (System.IntPtr javaReference, Android.Runtime.JniHandleOwnership transfer) [0x00015] in D:\temp\xamarin\XamAndroid\XamAndroid\XamApplication.cs:24 
05-09 15:22:14.785 E/mono    (30705):   at (wrapper managed-to-native) System.Reflection.MonoCMethod:InternalInvoke (System.Reflection.MonoCMethod,object,object[],System.Exception&)
05-09 15:22:14.785 E/mono    (30705):   at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00002] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:661 
05-09 15:22:14.785 E/mono    (30705):    --- End of inner exception stack trace ---
05-09 15:22:14.788 E/mono-rt (30705): [ERROR] FATAL UNHANDLED EXCEPTION: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidProgramException: Invalid IL code in (wrapper dynamic-method) Android.Widget.HorizontalScrollView:Fling_Patch1 (object,int): IL_003c: endfinally
05-09 15:22:14.788 E/mono-rt (30705): 
05-09 15:22:14.788 E/mono-rt (30705): 
05-09 15:22:14.788 E/mono-rt (30705):   at (wrapper managed-to-native) System.RuntimeMethodHandle:GetFunctionPointer (intptr)
05-09 15:22:14.788 E/mono-rt (30705):   at System.RuntimeMethodHandle.GetFunctionPointer () [0x00000] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/corlib/System/RuntimeMethodHandle.cs:87 
05-09 15:22:14.788 E/mono-rt (30705):   at Harmony.ILCopying.Memory.GetMethodStart (System.Reflection.MethodBase method) [0x00007] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 15:22:14.788 E/mono-rt (30705):   at Harmony.PatchFunctions.UpdateWrapper (System.Reflection.MethodBase original, Harmony.PatchInfo patchInfo) [0x0004b] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 15:22:14.788 E/mono-rt (30705):   at Harmony.PatchProcessor.Patch () [0x00066] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 15:22:14.788 E/mono-rt (30705):   at Harmony.HarmonyInstance.<PatchAll>b__6_0 (System.Type type) [0x00022] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 15:22:14.788 E/mono-rt (30705):   at Harmony.CollectionExtensions.Do[T] (System.Collections.Generic.IEnumerable`1[T] sequence, System.Action`1[T] action) [0x00015] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 15:22:14.788 E/mono-rt (30705):   at Harmony.HarmonyInstance.PatchAll (System.Reflection.Assembly assembly) [0x00006] in <62ddd56beca247a7b59cdedc50f7b2a9>:0 
05-09 15:22:14.788 E/mono-rt (30705):   at XamAndroid.XamApplication..ctor (System.IntPtr javaReference, Android.Runtime.JniHandleOwnership transfer) [0x00015] in D:\temp\xamarin\XamAndroid\XamAndroid\XamApplication.cs:24 
05-09 15:22:14.788 E/mono-rt (30705):   at (wrapper managed-to-native) System.Reflection.MonoCMethod:InternalInvoke (System.Reflection.MonoCMethod,object,object[],System.Exception&)
05-09 15:22:14.788 E/mono-rt (30705):   at System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) [0x00002] in /Users/builder/data/lanes/4009/3a62f1ea/source/mono/mcs/class/corlib/System.Reflection/MonoMethod.cs:661 
05-09 15:22:14.788 E/mono-rt (30705):    --- End of inner exception stack trace ---

this is my code:

        [HarmonyPatch(typeof(HorizontalScrollView), "Fling", new Type[] {typeof(int)})]
        public class Patch
        {
            static bool Prefix(int velocityX)
            {
                // your code here
                return false;
            }
        }

from harmony.

alicint avatar alicint commented on May 12, 2024

yes the parameter name matches, (tried earlier with a wrong name and got another error)

tried setting DEBUG = true and got a directory not found error, it seems like Harmony is trying to write the log to /data/user/0/XamAndroid.XamAndroid/files/Desktop/harmony.log.txt address which doesn't exists on the phone, can it be changed?

from harmony.

pardeike avatar pardeike commented on May 12, 2024

At this point I have no direct plans to support Android. You are of course welcome to clone the repo and make the necessary changes yourself. Then again, I am not sure if the patcher will work at all on Android.

from harmony.

alicint avatar alicint commented on May 12, 2024

Ok Thanks for your help anyway. yeah I guess it might be tricky to make it work for xamarin.android since xamarin itself involves a lot of quirks and hacks to make android work. and ofc uses a striped down version of .net framework.

from harmony.

pardeike avatar pardeike commented on May 12, 2024

As you can see, at this point I'm not even supporting Microsoft Core .NET because of the way it works (although I have a pull request from a smart guy but I have not yet had the time to merge it).

Good luck and in case you get it to work I am more than happy to accept your changes into the project. It's just not a priority for me right now.

from harmony.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.