You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Godot游戏Mod系统动态加载DLL执行方法时触发受保护内存违规

Godot C# Mod系统调用_Ready方法触发内存访问错误

场景概述

在Godot中开发游戏Mod系统,允许Mod开发者使用C#编写代码并编译为DLL,由游戏加载后执行其中方法。

加载与调用代码

程序集加载代码

string dll = // 绝对路径...
if (File.Exists(dll)) {
   return Assembly.LoadFrom(dll);
}

Mod方法调用代码

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);
}

Mod示例代码

using Godot;

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

错误信息

调用Mod中Main类的_Ready方法时,触发致命错误:

Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

备注

  • 清楚该做法存在风险,自行处理,无需提及安全性问题。
  • dll路径、type、method和mod.Instance均不为空,排除这些环节的问题。

解决办法

1. 确保版本完全匹配

Mod编译使用的Godot版本、.NET运行时版本必须与主游戏完全一致,包括Godot SDK的补丁版本、.NET框架版本(如都是.NET 6)。版本不匹配会导致Godot API绑定失效,触发内存访问错误。

2. 让Mod类继承Godot基类并使用Godot初始化流程

Godot的C# API依赖自身的脚本上下文,直接用Activator.CreateInstance创建的实例没有经过Godot的初始化,调用GD类等API时会访问无效内存。

  • 修改Mod代码,让Main类继承自Node或Reference,并重写_Ready方法:
    using Godot;
    
    namespace TestMod
    {
        public class Main : Node
        {
            public override void _Ready()
            {
                GD.Print("Hello from the mod!");
            }
        }
    }
    
  • 修改调用逻辑,改用Godot的实例创建方式,比如通过GD.Load<Script>()加载类型后调用New()方法创建实例:
    // 替代Activator.CreateInstance的示例代码
    Script modScript = GD.Load<Script>($"res://Mods/{mod.Name}/Main.cs");
    mod.Instance = modScript.New();
    

3. 调整程序集加载方式

尝试使用Assembly.LoadFile替代Assembly.LoadFrom,加载时确保Mod程序集能正确引用主游戏中的Godot核心程序集,避免上下文冲突。

4. 捕获调用栈定位问题

在Visual Studio中附加到游戏进程,启用调试模式,捕获错误的完整调用栈,明确是哪一行代码触发的内存错误,便于精准排查。

内容的提问来源于stack exchange,提问作者GoogleCoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 05:42:37