Load native extension on .NET core via differentiated DllImports

pull/24853/head
Jan Tattermusch 4 years ago
parent 6b9ca6ce59
commit 37715e3422
  1. 41
      src/csharp/Grpc.Core/Internal/NativeExtension.cs
  2. 1714
      src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs
  3. 82
      templates/src/csharp/Grpc.Core/Internal/NativeMethods.Generated.cs.template

@ -117,6 +117,42 @@ namespace Grpc.Core.Internal
{
return LoadNativeMethodsXamarin();
}
if (PlatformApis.IsNetCore)
{
// On .NET Core, native libraries are a supported feature and the SDK makes
// sure that the native library is made available in the right location and that
// they will be discoverable by the [DllImport] default loading mechanism,
// even in some of the more exotic situations such as single file apps.
//
// While in theory, we could just [DllImport("grpc_csharp_ext")] for all the platforms
// and operating systems, the native libraries in the nuget package
// need to be laid out in a way that still allows things to work well under
// the legacy .NET Framework (where native libraries are a concept unknown to the runtime).
// Therefore, we use several flavors of the DllImport attribute
// (e.g. the ".x86" vs ".x64" suffix) and we choose the one we want at runtime.
// The classes with the list of DllImport'd methods are code generated,
// so having more than just one doesn't really bother us.
// on Windows, the DllImport("grpc_csharp_ext.x64") doesn't work for some reason,
// but DllImport("grpc_csharp_ext.x64.dll") does, so we need a special case for that.
bool useDllSuffix = PlatformApis.IsWindows;
if (PlatformApis.Is64Bit)
{
if (useDllSuffix)
{
return new NativeMethods(new NativeMethods.DllImportsFromSharedLib_x64_dll());
}
return new NativeMethods(new NativeMethods.DllImportsFromSharedLib_x64());
}
else
{
if (useDllSuffix)
{
return new NativeMethods(new NativeMethods.DllImportsFromSharedLib_x86_dll());
}
return new NativeMethods(new NativeMethods.DllImportsFromSharedLib_x86());
}
}
return new NativeMethods(LoadUnmanagedLibrary());
}
@ -139,6 +175,10 @@ namespace Grpc.Core.Internal
/// <summary>
/// Return native method delegates when running on the Xamarin platform.
/// On Xamarin, the standard <c>[DllImport]</c> loading logic just works
/// as the native library metadata is provided by the <c>AndroidNativeLibrary</c> or
/// <c>NativeReference</c> items in the Xamarin projects (injected automatically
/// by the Grpc.Core.Xamarin nuget).
/// WARNING: Xamarin support is experimental and work-in-progress. Don't expect it to work.
/// </summary>
private static NativeMethods LoadNativeMethodsXamarin()
@ -147,7 +187,6 @@ namespace Grpc.Core.Internal
{
return new NativeMethods(new NativeMethods.DllImportsFromSharedLib());
}
// not tested yet
return new NativeMethods(new NativeMethods.DllImportsFromStaticLib());
}

File diff suppressed because it is too large Load Diff

@ -63,6 +63,34 @@
% endfor
}
public NativeMethods(DllImportsFromSharedLib_x86 unusedInstance)
{
% for method in get_native_methods():
this.${method['name']} = DllImportsFromSharedLib_x86.${method['name']};
% endfor
}
public NativeMethods(DllImportsFromSharedLib_x64 unusedInstance)
{
% for method in get_native_methods():
this.${method['name']} = DllImportsFromSharedLib_x64.${method['name']};
% endfor
}
public NativeMethods(DllImportsFromSharedLib_x86_dll unusedInstance)
{
% for method in get_native_methods():
this.${method['name']} = DllImportsFromSharedLib_x86_dll.${method['name']};
% endfor
}
public NativeMethods(DllImportsFromSharedLib_x64_dll unusedInstance)
{
% for method in get_native_methods():
this.${method['name']} = DllImportsFromSharedLib_x64_dll.${method['name']};
% endfor
}
/// <summary>
/// Delegate types for all published native methods. Declared under inner class to prevent scope pollution.
/// </summary>
@ -87,7 +115,7 @@
}
/// <summary>
/// grpc_csharp_ext used a shared library (e.g on Unity Standalone and Android).
/// grpc_csharp_ext used as a shared library (e.g on Unity Standalone and Android).
/// </summary>
internal class DllImportsFromSharedLib
{
@ -98,5 +126,57 @@
public static extern ${method['returntype']} ${method['name']}(${method['params']});
% endfor
}
/// <summary>
/// grpc_csharp_ext used as a shared library (with x86 suffix)
/// </summary>
internal class DllImportsFromSharedLib_x86
{
private const string ImportName = "grpc_csharp_ext.x86";
% for method in get_native_methods():
[DllImport(ImportName)]
public static extern ${method['returntype']} ${method['name']}(${method['params']});
% endfor
}
/// <summary>
/// grpc_csharp_ext used as a shared library (with x64 suffix)
/// </summary>
internal class DllImportsFromSharedLib_x64
{
private const string ImportName = "grpc_csharp_ext.x64";
% for method in get_native_methods():
[DllImport(ImportName)]
public static extern ${method['returntype']} ${method['name']}(${method['params']});
% endfor
}
/// <summary>
/// grpc_csharp_ext used as a shared library (with x86.dll suffix)
/// </summary>
internal class DllImportsFromSharedLib_x86_dll
{
private const string ImportName = "grpc_csharp_ext.x86.dll";
% for method in get_native_methods():
[DllImport(ImportName)]
public static extern ${method['returntype']} ${method['name']}(${method['params']});
% endfor
}
/// <summary>
/// grpc_csharp_ext used as a shared library (with x64.dll suffix)
/// </summary>
internal class DllImportsFromSharedLib_x64_dll
{
private const string ImportName = "grpc_csharp_ext.x64.dll";
% for method in get_native_methods():
[DllImport(ImportName)]
public static extern ${method['returntype']} ${method['name']}(${method['params']});
% endfor
}
}
}

Loading…
Cancel
Save