Библиотека C# (Harmony) работает должным образом в редакторе Godot, но не работает в сборке Godot

Я пытаюсь использовать Harmony 2.3.3 с Godot 4.2.1, и в редакторе он работает как положено, но не в экспортированной сборке.

Я пытаюсь исправить префикс метода, и в редакторе метод успешно исправлен, но в экспортированной сборке метод не удается исправить, и выдается следующее исключение:

System.ArgumentException: GenericArguments[0], 'MonoMod.Utils.Cil.CecilILGenerator', on 'MonoMod.Utils.Cil.ILGeneratorProxy[TTarget]' violates the constraint of type 'TTarget'.
 ---> System.TypeLoadException: GenericArguments[0], 'MonoMod.Utils.Cil.CecilILGenerator', on 'MonoMod.Utils.Cil.ILGeneratorProxy[TTarget]' violates the constraint of type parameter 'TTarget'.
   at System.RuntimeTypeHandle.Instantiate(RuntimeType inst)
   at System.RuntimeType.MakeGenericType(Type[] instantiation)
   --- End of inner exception stack trace ---
   at System.RuntimeType.ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)
   at System.RuntimeType.MakeGenericType(Type[] instantiation)
   at MonoMod.Utils.Cil.ILGeneratorShim.GetProxy()
   at MonoMod.Utils.DynamicMethodDefinition.GetILGenerator()
   at HarmonyLib.MethodPatcher..ctor(MethodBase original, MethodBase source, List`1 prefixes, List`1 postfixes, List`1 transpilers, List`1 finalizers, Boolean debug)
   at HarmonyLib.PatchFunctions.UpdateWrapper(MethodBase original, PatchInfo patchInfo)
   at HarmonyLib.PatchProcessor.Patch()
   at HarmonyLib.Harmony.Patch(MethodBase original, HarmonyMethod prefix, HarmonyMethod postfix, HarmonyMethod transpiler, HarmonyMethod finalizer)
   at HarmonyTester.Test() in G:\Godot Projects\HarmonyExportIssue\HarmonyTesting\HarmonyTester.cs:line 24

Кажется, это какая-то проблема с зависимостями, как обсуждалось в этой проблеме на Harmony Github, но я понятия не имею, куда идти дальше и как решить эту проблему.

Минимальный воспроизводимый пример (Godot 4.2.1-моно)

Встроенная версия примера

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

После дополнительных исследований выяснилось, что это известная проблема с Godot и внешними файлами .dll. https://github.com/godotengine/godot/issues/75160

Это можно обойти, используя отражение, как описано в этом ответе: https://github.com/godotengine/godot/issues/75160#issuecomment-2071203840

public partial class ModLoader : Node
{
    public override void _Ready()
    {
        string modPath = ProjectSettings.GlobalizePath("user://TestMod.dll");

        var alc = AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly());
        Assembly assembly = alc.LoadFromAssemblyPath(modPath);

        Type t = assembly.GetType("TestMod.TestModInit");

        t.GetMethod("Init")?.Invoke(null, null);
    }
}

Обратите внимание, что во время выполнения вам нужно будет получить файл dll, используя

OS.GetExecutablePath().GetBaseDir().PathJoin(file: "dllname.dll")

вместо

Другие вопросы по теме

Использование FluentAssertions.Should().NotBeNull() вместо Assert.NotNull(record.Message) дает возможный запах NullReference
Есть ли способ обновить версию C# в Visual Studio до 12.0 при использовании платформы .NET?
Я могу установить .NET 8.0.301 (v8.0.6) с помощью dotnet-install.ps1, но не могу установить .NET 8.0.300 (v8.0.5) на своем компьютере с Windows 10 Pro
.NET не может установить исходящее соединение (тайм-аут)
Соединение строк с инвариантом культуры
HttpContext возвращает значение null на странице входа в Blazor
Как избежать бесконечного цикла перенаправления при объединении двух разных схем аутентификации (openIdConnect и ASP.NET Identity)?
Универсальный способ извлечения значений тегов из XML-документа в список List<string>
Обновление .NET 8 ISOLATED прекратило регистрацию информации, отладки
Невозможно распространить приложение MAUI iOS в магазине приложений VS2022. Задаче «CompileAppManifest» не было присвоено значение обязательного параметра «DefaultSdkVersion»