Comments (12)
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.
Make sure you follow the documentation on the wiki:
https://github.com/pardeike/Harmony/wiki/Patching
from harmony.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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)
- Incorrect code generation for exception block when patching `System.Net.WebClient::DownloadFile(System.Uri address, System.String fileName)` HOT 2
- Problem patching specific method with latest pre-release HOT 2
- Harmony CANNOT be used in Godot!!!! HOT 2
- Any restriction to hook .Net service? HOT 9
- Getting an instance from the TargetMethod patch HOT 1
- Using GeneratedRegex causes failed compile due to ReadOnlySpan HOT 2
- A crash after hook:The object's current state invalidates the operation HOT 2
- Harmony fails to patch method and throws exception in exported Godot build HOT 13
- NuGet Package reference assembly conflict HOT 8
- ModuleInitializerAttribute HOT 1
- RtDynamicMethod get MetadataToken throws InvalidOperationException HOT 2
- Patch on .net 7&8 throw TypeLoadException while debugging HOT 17
- Harmony 3.0: Utility Epic
- Investigate Testing the NuGet Package Directly HOT 3
- Add a Release Pipeline
- Hook exception: System.Exception: Cannot get result from void method System.Void HOT 2
- How to patch method of base class? HOT 1
- When applying a patch fails, the replacement's IL is not printed to the debug log HOT 2
- System.Exception: Parameter "xx" not found in method HOT 10
- SymbolExtensions does not resolve overriden method HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from harmony.