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

[C#] Fatal error. System.Runtime.InteropServices.SEHException (0x80004005): External component has thrown an exception. #74801

Closed
JonathanPicques opened this issue Mar 12, 2023 · 5 comments · Fixed by #75955

Comments

@JonathanPicques
Copy link

JonathanPicques commented Mar 12, 2023

Godot version

4.0.stable-mono

System information

Windows 10 64bits

Issue description

Calling WebRTCPeerConnection.CreateDataChannel in C# throws External component has thrown an exception.
But it works correctly if implemented in GDScript

Steps to reproduce

Setup a project with WebRTC and create an empty scene that derives from Node and assigns it this script:

using Godot;
using System;

public partial class Bug : Node
{
	public override void _Ready()
	{
		var peerConnection = new WebRtcPeerConnection();
		var peerDataChannel = peerConnection.CreateDataChannel("chat", new Godot.Collections.Dictionary {
			{"id", 42},
			{"negotiated", true},
		});
		GD.Print($"{peerDataChannel.GetId()}");
	}
}

Running this scene should show the game window opens and then immediately close with this stack trace in the console:

2023-03-12 03:10:57.853 DEBUG [10628] [rtc::impl::Init::doInit@110] Global initialization
2023-03-12 03:10:57.856 DEBUG [14980] [rtc::impl::Certificate::Generate@213] Generating certificate (OpenSSL)
ERROR: Condition "_instance_bindings != nullptr" is true.
   at: set_instance_binding (core/object/object.cpp:1689)
ERROR: Parameter "strong_gchandle.value" is null.
   at: setup_csharp_script_binding (modules/mono/csharp_script.cpp:1225)
ERROR: Condition "!script_binding.inited" is true. Returning: { nullptr }
   at: godotsharp_internal_unmanaged_get_instance_binding_managed (modules/mono/glue/runtime_interop.cpp:234)
ERROR: Parameter "strong_gchandle.value" is null.
   at: setup_csharp_script_binding (modules/mono/csharp_script.cpp:1225)
ERROR: Condition "!script_binding.inited" is true. Returning: { nullptr }
   at: godotsharp_internal_unmanaged_instance_binding_create_managed (modules/mono/glue/runtime_interop.cpp:247)
ERROR: FATAL: Condition "!rc_owner" is true.
   at: _instance_binding_reference_callback (modules/mono/csharp_script.cpp:1311)
Fatal error. System.Runtime.InteropServices.SEHException (0x80004005): External component has thrown an exception.
   at Godot.NativeInterop.NativeFuncs.godotsharp_ref_destroy(Godot.NativeInterop.godot_ref ByRef)
   at Godot.NativeInterop.godot_ref.Dispose()
   at Godot.NativeCalls.godot_icall_2_1152(IntPtr, IntPtr, System.String, Godot.NativeInterop.godot_dictionary)
   at Godot.WebRtcPeerConnection.CreateDataChannel(System.String, Godot.Collections.Dictionary)
   at Bug._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 Bug.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*)

Attaching the same working code in gdscript:

extends Node

# this works correctly in gdscript
func _ready():
	var peerConnection := WebRTCPeerConnection.new()
	var peerDataChannel := peerConnection.create_data_channel("chat", {
		"id": 4,
		"negotiated": true,
	})
	print(peerDataChannel.get_id())

Minimal reproduction project

WebRtcBug.zip

(Only WebRtc Windows DLLs are included, otherwise that file would be too big, the whole zip can be found here : https://github.com/godotengine/webrtc-native/releases/download/1.0.0-rc1/godot-gdnative-webrtc.zip)

@RedworkDE
Copy link
Member

This is caused by C# not supporting use of classes from GDExtensions yet. Tho I don't think this is explicitly documented anywhere yet, especially not that receiving a GDExtension registered class from somewhere causes crashes.

(Also for the future please always include a full MRP, even if you include the most relevant snippets in the issue directly.)

@JonathanPicques
Copy link
Author

@RedworkDE Thanks for your answer :) Is there an issue to track that feature?

(I added a full MRP in my initial post)

@RedworkDE
Copy link
Member

AFAIK no, so it's this one now.

@mihe
Copy link
Contributor

mihe commented Apr 11, 2023

This is caused by C# not supporting use of classes from GDExtensions yet. Tho I don't think this is explicitly documented anywhere yet, especially not that receiving a GDExtension registered class from somewhere causes crashes.

This seems to also (perhaps unsurprisingly) affect things like GDExtension-based classes that derive from PhysicsServer3DExtension, PhysicsDirectBodyState3DExtension, and PhysicsDirectSpaceState3DExtension, making it more or less impossible to use alternative physics engines from C#, unless implemented as a module.

A somewhat crude fix, that I believe could serve as a temporary fix for the "receiving" part, is to keep traversing the classinfo hierarchy in setup_csharp_script_binding as long as classinfo->gdextension is a valid pointer. So you would basically treat GDExtension classes the same way you would if they were not exposed.

On top of that you would need to also keep traversing if the type name is either PhysicsServer2DExtension or PhysicsServer3DExtension, since those are currently being filtered out when generating bindings, courtesy of #59286.

I'll create a PR for it and we can maybe discuss it there instead.

@RedworkDE

This comment was marked as outdated.

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

Successfully merging a pull request may close this issue.

5 participants