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

Calling a C# interface method crashes Godot immediately #71175

Closed
johnfn opened this issue Jan 10, 2023 · 3 comments
Closed

Calling a C# interface method crashes Godot immediately #71175

johnfn opened this issue Jan 10, 2023 · 3 comments

Comments

@johnfn
Copy link

johnfn commented Jan 10, 2023

Godot version

4.0 beta10

System information

MacOS Catalina

Issue description

Calling an interface method crashes Godot immediately. The game closes with no stack trace.

Steps to reproduce

Put this code on any node:

using Godot;
using System;

interface IFoo {
  public void TestMethod() {
    GD.Print("Hello");
  }
}

public partial class Test : Node2D, IFoo {
  public override void _Ready() {
    TestMethod();
  }
  
  public void TestMethod() {
    (this as IFoo).TestMethod();
  }
}

Minimal reproduction project

https://github.com/johnfn/CsharpGodotCrashRepro

@raulsntos
Copy link
Member

The code in the MRP results in a stackoverflow because TestMethod calls itself. It seems your intention was for the Test.TestMethod implementation to call the default interface implementation but by implementing the method you are essentially overriding the interface method.

This is the output I get in the terminal when launching the Godot project in Linux:

Stack overflow.
Repeat 261612 times:
--------------------------------
   at Test.TestMethod()
--------------------------------
   at Test._Ready()
   at Godot.Node.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name ByRef, Godot.NativeInterop.NativeVariantPtrArgs, Godot.NativeInterop.godot_variant ByRef)
   at Godot.CanvasItem.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name ByRef, Godot.NativeInterop.NativeVariantPtrArgs, Godot.NativeInterop.godot_variant ByRef)
   at Godot.Node2D.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name ByRef, Godot.NativeInterop.NativeVariantPtrArgs, Godot.NativeInterop.godot_variant ByRef)
   at Test.InvokeGodotClassMethod(Godot.NativeInterop.godot_string_name ByRef, Godot.NativeInterop.NativeVariantPtrArgs, Godot.NativeInterop.godot_variant ByRef)
   at 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*)
zsh: IOT instruction (core dumped)  godot4

I think what you are looking for is this:

public partial class Test : IFoo
{
	public void TestMethod()
	{
		base(IFoo).TestMethod();
	}
}

This feature was cut from C# 8.0 but the intention is to bring it back in a future version of the language, see https://github.com/dotnet/csharplang/blob/main/meetings/2019/LDM-2019-04-29.md#default-interface-implementations-and-base-calls.

You can follow the base(T) feature in the champion issue: dotnet/csharplang#2337.

Since this is not a Godot issue but a limitation of the C# language I'll close this issue.

@raulsntos raulsntos closed this as not planned Won't fix, can't repro, duplicate, stale Jan 11, 2023
@johnfn
Copy link
Author

johnfn commented Jan 11, 2023

Hmm, even if I got the code wrong, I disagree that this is not an issue at all: the game should certainly not crash without so much as an error message.

@raulsntos
Copy link
Member

Unfortunately we don't have any control over stackoverflows, it's a special type of exception that can't really be catched.

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

3 participants