Я пытаюсь заменить метод в загрузчике плагинов (например, Bukkit for Minecraft) во время выполнения. Я не могу изменить файл сборки непосредственно в этом экземпляре. Вся цель состоит в том, чтобы иметь возможность сказать, когда вызываются методы. И отмените их, если необходимо. Как только мой плагин загружен, я запускаю следующий код:C# указатель метода изменения .NET 3.5
public static void PluginLoaded()
{
replace();
}
public static void replace()
{
MethodInfo oldMethod, newMethod;
oldMethod = typeof(<other assembly>).GetMethod("<method name>", BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic,null,new Type[]{typeof(ushort)},null);
newMethod = typeof(NewEvents).GetMethod("<method name>", BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic, null, new Type[] { typeof(ushort) }, null);
RuntimeHelpers.PrepareMethod(oldMethod.MethodHandle);
RuntimeHelpers.PrepareMethod(newMethod.MethodHandle);
ReplaceInner(oldMethod, newMethod);
}
static void ReplaceInner(MethodInfo methodToReplace, MethodInfo methodToInject)
{
unsafe
{
if (IntPtr.Size == 4)
{
int* inj = (int*)methodToInject.MethodHandle.Value.ToPointer() + 2;
int* tar = (int*)methodToReplace.MethodHandle.Value.ToPointer() + 2;
*tar = *inj;
}
else
{
ulong* inj = (ulong*)methodToInject.MethodHandle.Value.ToPointer() + 1;
ulong* tar = (ulong*)methodToReplace.MethodHandle.Value.ToPointer() + 1;
*tar = *inj;
}
}
}
Он отлично работает, пока оригинальная программа не попытается вызвать измененный метод. Когда он делает это, вся программа останавливается, и я получаю access volation. Как это исправить?
я беру его у вас есть плагин архитектуры приложения и пытаются иметь логику обертки для вызовов метода отслеживания в плагине (-ах)? Пробовали ли вы систему подстановки зависимостей, такую как Managed Extensibility Framework или Microsoft Unity? Они предоставляют способы реализации оберток вокруг динамически загружаемых сборок, чтобы делать такие вещи. – ajawad987
Какая версия рамки? –
Попробуйте, не называя 'RuntimeHelpers.PrepareMethod()'. –