Repository: godot
Issue: GDNative DLL unloading bug causes a crash when you quit your game
Labels: bug,topic:gdextension,crash

### Godot version

v3.5.stable.official [991bb6ac7].

### System information

Windows 10, GLES 3, RTX 2070

### Issue description

References to GDNative DLLs seems fundamentally broken with regards to game shutdown when a GDNative  DLL is reloadable.  It appears that objects allocated by the DLL are still referenced after the DLL is unloaded.  I believe the scene is crashing silently on exit after it receives the `NOTIFICATION_WM_QUIT_REQUEST` notification but before it receives `NOTIFICATION_EXIT_WORLD`.  I have included a demo project that reproduces the issue with very minimal code.  Sometimes this can cause Windows to flag the executable as not being allowed to call `FreeLibrary` anymore which requires a registry edit to fix.

This is a major issue that fundamentally breaks GDNative in Godot Editor for anything except the most trivial projects as:
1. it can cause Windows to restrict disable `FreeLibrary` for the executable, and
2. debugging the app from the editor, the editor scripts will fail to trigger quit notifications.

This issue might be the same as #61543 but I am not certain.  Either way **this** issue includes a project to reproduce the issue.

### Steps to reproduce

1. Open the attached project and compile GDNative/godot-cpp with `scons platform=windows generate_bindings=yes` and then the GDNative DLL in the parent directory with `scons platform=windows`.
4. Ensure the DLL has been compiled to `Project\GDNative\win64\gdnativecrashdemo.dll`.
5. Open the project in Godot and run it **but do not let the mouse enter the client part of the game window**.  You must not cause the generation of mouse input events.
6. Quit the game by clicking the X in the top right corner.
7. Notice the following output in the Godot editor.  Pay attention to the last two lines:

```
MyScript::_init
SubsceneScript::_init
MyScript::_init
MyScript::_ready
SubsceneScript::_init
MyScript::_ready:  We have a subscene.
SubsceneScript::_ready
SubsceneScript::_notification NOTIFICATION_PREDELETE
MyScript::_notification NOTIFICATION_PREDELETE
```

8. Run the project again but **this time move the mouse over the client area of the game window**.  You are doing this to generate input mouse events.
9. Quit the game by clicking the X in the top right corner.
10. Notice the following output in the Godot editor:

```
MyScript::_init
SubsceneScript::_init
MyScript::_init
MyScript::_ready
SubsceneScript::_init
MyScript::_ready:  We have a subscene.
SubsceneScript::_ready
MyScript::_init
SubsceneScript::_init
```

11. Specifically notice that the following lines are missing from the editor output:

```
SubsceneScript::_notification NOTIFICATION_PREDELETE
MyScript::_notification NOTIFICATION_PREDELETE
```

12.  Now open the file `GDNative\src\MyScript.cpp`, go to line 56, and comment out `get_viewport();` and recompile.
13.  Now, every time you run the app it will shutdown properly.
14.  This implies that just calling `get_viewport()` causes something to happen that breaks app shutdown.  My best guess is that ultimately the objects allocated by the DLL are being accessed after the DLL is unloaded so `NOTIFICATION_PREDELETE` can never be processed.  
15.  Note that this is just not a `get_viewport()` issue.  I have had this happen multiple times.  For example if you add a function to a GDNative object and pass in the Scene's root object as a parameter.  That function can be completely empty and the following shutdown error will occur.

### Minimal reproduction project

[GDNativeCrashDemo.zip](https://github.com/godotengine/godot/files/9477542/GDNativeCrashDemo.zip)