summaryrefslogtreecommitdiff
path: root/modules/mono/glue
diff options
context:
space:
mode:
authorIgnacio Roldán Etcheverry <ignalfonsore@gmail.com>2022-02-27 21:57:52 +0100
committerIgnacio Roldán Etcheverry <ignalfonsore@gmail.com>2022-08-22 03:36:51 +0200
commit4b90d162502d65f20a89331898cd8a0b3eea8fe2 (patch)
tree3e1efc5a5638676aabe32e67f3ed342a8dbe808a /modules/mono/glue
parent18f805b3aad2be838a7396f18d4ebd99182b6935 (diff)
C#: Initial NativeAOT support
This commit adds initial support for games exported as NativeAOT shared libraries. At this moment, the NativeAOT runtime is experimental. Additionally, Godot is not trim-safe as it still makes some use of reflection. For the time being, a rd.xml file is needed to prevent code triming: ``` <Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata"> <Application> <Assembly Name="GodotSharp" Dynamic="Required All" /> <Assembly Name="GAME_ASSEMBLY" Dynamic="Required All" /> </Application> </Directives> ``` These are the csproj changes for publishing: ``` <PropertyGroup> <NativeLib>Shared</NativeLib> </PropertyGroup> <ItemGroup> <RdXmlFile Include="rd.xml" /> <PackageReference Include="Microsoft.DotNet.ILCompiler" Version="7.0.0-*" /> </ItemGroup> ``` More info: - https://github.com/dotnet/runtimelab/blob/feature/NativeAOT/docs/using-nativeaot/compiling.md - https://github.com/dotnet/runtimelab/tree/feature/NativeAOT/samples/NativeLibrary - https://github.com/dotnet/runtimelab/blob/feature/NativeAOT/docs/using-nativeaot/rd-xml-format.md
Diffstat (limited to 'modules/mono/glue')
-rw-r--r--modules/mono/glue/GodotSharp/GodotPlugins/Main.cs12
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs14
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/GodotDllImportResolver.cs25
3 files changed, 26 insertions, 25 deletions
diff --git a/modules/mono/glue/GodotSharp/GodotPlugins/Main.cs b/modules/mono/glue/GodotSharp/GodotPlugins/Main.cs
index 0cb9e57530..2a2e147eaa 100644
--- a/modules/mono/glue/GodotSharp/GodotPlugins/Main.cs
+++ b/modules/mono/glue/GodotSharp/GodotPlugins/Main.cs
@@ -20,22 +20,26 @@ namespace GodotPlugins
AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly()) ??
AssemblyLoadContext.Default;
+ private static DllImportResolver? _dllImportResolver;
+
// Right now we do it this way for simplicity as hot-reload is disabled. It will need to be changed later.
[UnmanagedCallersOnly]
// ReSharper disable once UnusedMember.Local
- private static unsafe godot_bool InitializeFromEngine(godot_bool editorHint,
+ private static unsafe godot_bool InitializeFromEngine(IntPtr godotDllHandle, godot_bool editorHint,
PluginsCallbacks* pluginsCallbacks, ManagedCallbacks* managedCallbacks)
{
try
{
+ _dllImportResolver = new GodotDllImportResolver(godotDllHandle).OnResolveDllImport;
+
SharedAssemblies.Add(CoreApiAssembly.GetName());
- NativeLibrary.SetDllImportResolver(CoreApiAssembly, GodotDllImportResolver.OnResolveDllImport);
+ NativeLibrary.SetDllImportResolver(CoreApiAssembly, _dllImportResolver);
if (editorHint.ToBool())
{
_editorApiAssembly = Assembly.Load("GodotSharpEditor");
SharedAssemblies.Add(_editorApiAssembly.GetName());
- NativeLibrary.SetDllImportResolver(_editorApiAssembly, GodotDllImportResolver.OnResolveDllImport);
+ NativeLibrary.SetDllImportResolver(_editorApiAssembly, _dllImportResolver);
}
*pluginsCallbacks = new()
@@ -97,7 +101,7 @@ namespace GodotPlugins
var assembly = LoadPlugin(assemblyPath);
- NativeLibrary.SetDllImportResolver(assembly, GodotDllImportResolver.OnResolveDllImport);
+ NativeLibrary.SetDllImportResolver(assembly, _dllImportResolver!);
var method = assembly.GetType("GodotTools.GodotSharpEditor")?
.GetMethod("InternalCreateInstance",
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs
index 71736a65c7..61987c6466 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs
@@ -39,7 +39,12 @@ namespace Godot.Bridge
try
{
- Type nativeType = TypeGetProxyClass(nativeTypeName);
+ using var stringName = StringName.CreateTakingOwnershipOfDisposableValue(
+ NativeFuncs.godotsharp_string_name_new_copy(CustomUnsafe.AsRef(nativeTypeName)));
+ string nativeTypeNameStr = stringName.ToString();
+
+ Type nativeType = TypeGetProxyClass(nativeTypeNameStr) ?? throw new InvalidOperationException(
+ "Wrapper class not found for type: " + nativeTypeNameStr);
var obj = (Object)FormatterServices.GetUninitializedObject(nativeType);
var ctor = nativeType.GetConstructor(
@@ -171,12 +176,9 @@ namespace Godot.Bridge
}
}
- private static unsafe Type TypeGetProxyClass(godot_string_name* nativeTypeName)
+ private static Type TypeGetProxyClass(string nativeTypeNameStr)
{
// Performance is not critical here as this will be replaced with a generated dictionary.
- using var stringName = StringName.CreateTakingOwnershipOfDisposableValue(
- NativeFuncs.godotsharp_string_name_new_copy(CustomUnsafe.AsRef(nativeTypeName)));
- string nativeTypeNameStr = stringName.ToString();
if (nativeTypeNameStr[0] == '_')
nativeTypeNameStr = nativeTypeNameStr.Substring(1);
@@ -186,7 +188,7 @@ namespace Godot.Bridge
if (wrapperType == null)
{
wrapperType = AppDomain.CurrentDomain.GetAssemblies()
- .First(a => a.GetName().Name == "GodotSharpEditor")
+ .FirstOrDefault(a => a.GetName().Name == "GodotSharpEditor")?
.GetType("Godot." + nativeTypeNameStr);
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/GodotDllImportResolver.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/GodotDllImportResolver.cs
index c4a90625c3..5579992d2b 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/GodotDllImportResolver.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/GodotDllImportResolver.cs
@@ -6,9 +6,16 @@ using System.Runtime.InteropServices;
namespace Godot.NativeInterop
{
- public static class GodotDllImportResolver
+ public class GodotDllImportResolver
{
- public static IntPtr OnResolveDllImport(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
+ private IntPtr _internalHandle;
+
+ public GodotDllImportResolver(IntPtr internalHandle)
+ {
+ _internalHandle = internalHandle;
+ }
+
+ public IntPtr OnResolveDllImport(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
{
if (libraryName == "__Internal")
{
@@ -18,7 +25,7 @@ namespace Godot.NativeInterop
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
- return Linux.dlopen(IntPtr.Zero, Linux.RTLD_LAZY);
+ return _internalHandle;
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
@@ -40,18 +47,6 @@ namespace Godot.NativeInterop
public static extern IntPtr dlopen(IntPtr path, int mode);
}
- private static class Linux
- {
- // libdl.so was resulting in DllNotFoundException, for some reason...
- // libcoreclr.so should work with both CoreCLR and the .NET Core version of Mono.
- private const string SystemLibrary = "libcoreclr.so";
-
- public const int RTLD_LAZY = 1;
-
- [DllImport(SystemLibrary)]
- public static extern IntPtr dlopen(IntPtr path, int mode);
- }
-
private static class Win32
{
private const string SystemLibrary = "Kernel32.dll";