从动态加载的程序集中执行方法时发生受保护的内存冲突

问题描述 投票:0回答:1

我正在 Godot 中为我的游戏制作一个模组系统,模组制作者用 C# 编写代码并将其编译为 DLL,游戏从中加载并执行方法。

compile方法的相关部分(返回一个Assembly)

string dll = //the absolute path...
if (File.Exists(dll)) {
   return Assembly.LoadFrom(dll);
}

然后我调用这样的方法:

    private void ExecuteModMethod(Mod mod, string methodName, object[] methodParameters)
    {
        if (!useMods) return;
        Type type = mod.Assembly.GetType(mod.Name+".Main");
        if (type == null) return;
        MethodInfo method = type.GetMethod(methodName);
    
        mod.Instance = Activator.CreateInstance(type);
        if (method == null) return;
        method.Invoke(mod.Instance, methodParameters);
    }

当我尝试调用

_Ready
方法(Godot init 方法,模组作者也应该命名他们的 init 方法)时,我得到
Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

这是模组中唯一的代码文件:

using Godot;


namespace TestMod
{
    public class Main
    {
        //Called when the game is loaded
        public void _Ready()
        {
            GD.Print("Hello from the mod!");
        }
    }
}

我对 DLL 和此类事情了解不多,因此感谢您的帮助。我只需要错误消失,因为它停止了应用程序的执行,因此没有调用任何方法。

注意事项

  • 我知道这确实很危险,改装者可能会包含恶意软件。我会处理这个问题,你不需要提及它有多危险,谢谢。
  • 这是唯一抛出的错误,dll路径、
    type
    method
    mod.Instance
    都不为空。这不是问题。
c# dynamic dll godot dllimport
1个回答
0
投票

戈多的首字母有 3 个

AssemblyLoadContext

  • Internal.Runtime.InteropServices.IsolatedComponentLoadContext
  • GodotPlugins.PluginLoadContext
  • System.Runtime.Loader.DefaultAssemblyLoadContext

你的脚本被加载到第二个ALC中,所以你也需要将你的mod程序集加载到这个ALC中,ALC将解析Godot的程序集。

Assembly.LoadFrom
将程序集加载到默认程序集,您需要将其替换为以下代码:

var executingASM = Assembly.GetExecutingAssembly();
var executingALC = AssemblyLoadContext.GetLoadContext(executingASM);
var fullDllPath = Path.GetFullPath(dll);
return executingALC.LoadFromAssemblyPath(fullDllPath);
© www.soinside.com 2019 - 2024. All rights reserved.