Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loading external DLL at runtime errors #75160

Open
duck-117 opened this issue Mar 21, 2023 · 7 comments
Open

Loading external DLL at runtime errors #75160

duck-117 opened this issue Mar 21, 2023 · 7 comments

Comments

@duck-117
Copy link

Godot version

v4.0.stable.mono.official [92bee43]

System information

Arch Linux

Issue description

When i try to load an external dll from the user data folder (via System.Reflection.Assembly.LoadFile) and invoke a static method it gives this error:


  <C++ Error>    System.Reflection.TargetInvocationException
  <C++ Source>   :0 @ System.Object System.RuntimeMethodHandle.InvokeMethod(System.Object , System.Void** , System.Signature , Boolean )
  <Stack Trace>  :0 @ System.Object System.RuntimeMethodHandle.InvokeMethod(System.Object , System.Void** , System.Signature , Boolean )
                 :0 @ System.Object System.Reflection.MethodInvoker.Invoke(System.Object , System.IntPtr* , System.Reflection.BindingFlags )
                 :0 @ --- End of inner exception stack trace ---()
                 :0 @ System.Object System.Reflection.MethodInvoker.Invoke(System.Object , System.IntPtr* , System.Reflection.BindingFlags )
                 :0 @ System.Object System.Reflection.RuntimeMethodInfo.Invoke(System.Object , System.Reflection.BindingFlags , System.Reflection.Binder , System.Object[] , System.Globalization.CultureInfo )
                 ModLoader.cs:17 @ void ModdedGame.Modding.ModLoader._Ready()
                 Node.cs:1782 @ Boolean Godot.Node.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name& , Godot.NativeInterop.NativeVariantPtrArgs , Godot.NativeInterop.godot_variant& )
                 ModdedGame.Modding.ModLoader_ScriptMethods.generated.cs:26 @ Boolean ModdedGame.Modding.ModLoader.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name& , Godot.NativeInterop.NativeVariantPtrArgs , Godot.NativeInterop.godot_variant& )
                 CSharpInstanceBridge.cs:24 @ Godot.NativeInterop.godot_bool Godot.Bridge.CSharpInstanceBridge.Call(IntPtr , Godot.NativeInterop.godot_string_name* , Godot.NativeInterop.godot_variant** , Int32 , Godot.NativeInterop.godot_variant_call_error* , Godot.NativeInterop.godot_variant* )

I expect it to load the dll and run the method.

Steps to reproduce

  1. Download ModLoader project and build.
  2. Download TestMod project and build.
  3. Move the TestMod.dll file from res://.godot/mono/temp/bin/Debug to user://
  4. Run ModLoader TestScene
  5. Open error log

Minimal reproduction project

ModLoader.zip
TestMod.zip

@Calinou
Copy link
Member

Calinou commented Mar 21, 2023

@RedworkDE
Copy link
Member

This is unrelated to the linked issue, which is about loading native libraries in 3.x

This issue is caused using a library that uses GodotSharp (eg another godot project here) because of how the ALCs are set up, that library doesn't use the existing instance of GodotSharp and tries to load a new instance instead, which fails as the assembly is not in any load path.

Notably when exporting the project, GodotSharp can be found and a second instance will be loaded, but because this is a new instance it does not have to hooks into the engine loaded and thus the exported project crashes with an AV when the loaded library tries to use any native function, (GD.Print here)

@issfire
Copy link

issfire commented Oct 5, 2023

I'm running into this issue as well on 4.1

From my understanding this would mean that "Live Updating" C# code is effectively broken (as it'll likely reference GodotSharp)

Is there any workaround to this?

@misleadingname
Copy link

Still very much sadly present in v4.3.dev2.mono.official [3524346].

@nexacopic

This comment was marked as off-topic.

@misleadingname
Copy link

Still present in v4.3.dev5.mono.official [89f70e9].

@raulsntos
Copy link
Member

As explained by @RedworkDE in #75160 (comment) you have to make sure to use the same isolated AssemblyLoadContext when loading assemblies.

Here's an example, I modified the ModLoader class from the MRP to use the correct ALC:

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants