aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/csharp/Grpc.Core.Tests/PInvokeTest.cs14
-rw-r--r--src/csharp/Grpc.Core/Grpc.Core.csproj23
-rw-r--r--src/csharp/Grpc.Core/GrpcEnvironment.cs16
-rw-r--r--src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs70
-rw-r--r--src/csharp/Grpc.Core/Internal/CStringSafeHandle.cs5
-rw-r--r--src/csharp/Grpc.Core/Internal/CallCredentialsSafeHandle.cs10
-rw-r--r--src/csharp/Grpc.Core/Internal/CallSafeHandle.cs95
-rw-r--r--src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs20
-rw-r--r--src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs17
-rw-r--r--src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs36
-rw-r--r--src/csharp/Grpc.Core/Internal/CompletionQueueEvent.cs5
-rw-r--r--src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs27
-rw-r--r--src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs35
-rw-r--r--src/csharp/Grpc.Core/Internal/NativeExtension.cs158
-rw-r--r--src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs7
-rw-r--r--src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs15
-rw-r--r--src/csharp/Grpc.Core/Internal/NativeMethods.cs816
-rw-r--r--src/csharp/Grpc.Core/Internal/PlatformApis.cs110
-rw-r--r--src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs16
-rw-r--r--src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs40
-rw-r--r--src/csharp/Grpc.Core/Internal/Timespec.cs28
-rw-r--r--src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs158
-rw-r--r--src/csharp/Grpc.Core/NativeDeps.Linux.targets9
-rw-r--r--src/csharp/Grpc.Core/NativeDeps.Mac.targets9
-rw-r--r--src/csharp/Grpc.Core/NativeDeps.Windows.targets9
-rw-r--r--src/csharp/Grpc.Core/NativeDeps.targets28
26 files changed, 1412 insertions, 364 deletions
diff --git a/src/csharp/Grpc.Core.Tests/PInvokeTest.cs b/src/csharp/Grpc.Core.Tests/PInvokeTest.cs
index af55cb0566..ea6572e7c0 100644
--- a/src/csharp/Grpc.Core.Tests/PInvokeTest.cs
+++ b/src/csharp/Grpc.Core.Tests/PInvokeTest.cs
@@ -45,13 +45,9 @@ namespace Grpc.Core.Tests
{
public class PInvokeTest
{
- int counter;
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern GRPCCallError grpcsharp_test_callback([MarshalAs(UnmanagedType.FunctionPtr)] OpCompletionDelegate callback);
+ static readonly NativeMethods Native = NativeMethods.Get();
- [DllImport("grpc_csharp_ext.dll")]
- static extern IntPtr grpcsharp_test_nop(IntPtr ptr);
+ int counter;
/// <summary>
/// (~1.26us .NET Windows)
@@ -87,7 +83,7 @@ namespace Grpc.Core.Tests
1000000, 10000000,
() =>
{
- grpcsharp_test_callback(handler);
+ Native.grpcsharp_test_callback(handler);
});
Assert.AreNotEqual(0, counter);
}
@@ -106,7 +102,7 @@ namespace Grpc.Core.Tests
10000, 10000,
() =>
{
- grpcsharp_test_callback(new OpCompletionDelegate(Handler));
+ Native.grpcsharp_test_callback(new OpCompletionDelegate(Handler));
});
Assert.AreNotEqual(0, counter);
}
@@ -122,7 +118,7 @@ namespace Grpc.Core.Tests
1000000, 100000000,
() =>
{
- grpcsharp_test_nop(IntPtr.Zero);
+ Native.grpcsharp_test_nop(IntPtr.Zero);
});
}
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
index 852b212114..ef4ec70a4a 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -19,7 +19,6 @@
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <NativeDependenciesConfiguration>Debug</NativeDependenciesConfiguration>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -27,7 +26,6 @@
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <NativeDependenciesConfiguration>Release</NativeDependenciesConfiguration>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -38,7 +36,6 @@
<WarningLevel>4</WarningLevel>
<SignAssembly>True</SignAssembly>
<AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
- <NativeDependenciesConfiguration>Release</NativeDependenciesConfiguration>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
@@ -52,6 +49,10 @@
<Compile Include="AsyncAuthInterceptor.cs" />
<Compile Include="CallCredentials.cs" />
<Compile Include="IClientStreamWriter.cs" />
+ <Compile Include="Internal\NativeMethods.cs" />
+ <Compile Include="Internal\PlatformApis.cs" />
+ <Compile Include="Internal\NativeExtension.cs" />
+ <Compile Include="Internal\UnmanagedLibrary.cs" />
<Compile Include="Internal\NativeMetadataCredentialsPlugin.cs" />
<Compile Include="Internal\INativeCall.cs" />
<Compile Include="IServerStreamWriter.cs" />
@@ -131,20 +132,6 @@
<None Include="Grpc.Core.nuspec" />
<None Include="packages.config" />
</ItemGroup>
- <Choose>
- <!-- Under older versions of Monodevelop, Choose is not supported and is just
- ignored, which gives us the desired effect. -->
- <When Condition=" '$(OS)' != 'Unix' ">
- <ItemGroup>
- <Content Include="..\..\..\vsprojects\$(NativeDependenciesConfiguration)\grpc_csharp_ext.dll">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </Content>
- </ItemGroup>
- </When>
- <Otherwise />
- </Choose>
+ <Import Project="NativeDeps.targets" />
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
- <ItemGroup />
- <ItemGroup />
- <ItemGroup />
</Project> \ No newline at end of file
diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs
index e7c04185c2..3797100fc6 100644
--- a/src/csharp/Grpc.Core/GrpcEnvironment.cs
+++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs
@@ -47,15 +47,6 @@ namespace Grpc.Core
{
const int THREAD_POOL_SIZE = 4;
- [DllImport("grpc_csharp_ext.dll")]
- static extern void grpcsharp_init();
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern void grpcsharp_shutdown();
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern IntPtr grpcsharp_version_string(); // returns not-owned const char*
-
static object staticLock = new object();
static GrpcEnvironment instance;
static int refCount;
@@ -136,7 +127,6 @@ namespace Grpc.Core
/// </summary>
private GrpcEnvironment()
{
- NativeLogRedirector.Redirect();
GrpcNativeInit();
completionRegistry = new CompletionRegistry(this);
threadPool = new GrpcThreadPool(this, THREAD_POOL_SIZE);
@@ -181,18 +171,18 @@ namespace Grpc.Core
/// </summary>
internal static string GetCoreVersionString()
{
- var ptr = grpcsharp_version_string(); // the pointer is not owned
+ var ptr = NativeMethods.Get().grpcsharp_version_string(); // the pointer is not owned
return Marshal.PtrToStringAnsi(ptr);
}
internal static void GrpcNativeInit()
{
- grpcsharp_init();
+ NativeMethods.Get().grpcsharp_init();
}
internal static void GrpcNativeShutdown()
{
- grpcsharp_shutdown();
+ NativeMethods.Get().grpcsharp_shutdown();
}
/// <summary>
diff --git a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
index 3a96414bea..256d2e3c83 100644
--- a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs
@@ -42,47 +42,7 @@ namespace Grpc.Core.Internal
/// </summary>
internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid
{
- [DllImport("grpc_csharp_ext.dll")]
- static extern BatchContextSafeHandle grpcsharp_batch_context_create();
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern IntPtr grpcsharp_batch_context_recv_initial_metadata(BatchContextSafeHandle ctx);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern IntPtr grpcsharp_batch_context_recv_message_length(BatchContextSafeHandle ctx);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern void grpcsharp_batch_context_recv_message_to_buffer(BatchContextSafeHandle ctx, byte[] buffer, UIntPtr bufferLen);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern StatusCode grpcsharp_batch_context_recv_status_on_client_status(BatchContextSafeHandle ctx);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern IntPtr grpcsharp_batch_context_recv_status_on_client_details(BatchContextSafeHandle ctx); // returns const char*
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern IntPtr grpcsharp_batch_context_recv_status_on_client_trailing_metadata(BatchContextSafeHandle ctx);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern CallSafeHandle grpcsharp_batch_context_server_rpc_new_call(BatchContextSafeHandle ctx);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern IntPtr grpcsharp_batch_context_server_rpc_new_method(BatchContextSafeHandle ctx); // returns const char*
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern IntPtr grpcsharp_batch_context_server_rpc_new_host(BatchContextSafeHandle ctx); // returns const char*
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern Timespec grpcsharp_batch_context_server_rpc_new_deadline(BatchContextSafeHandle ctx);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern IntPtr grpcsharp_batch_context_server_rpc_new_request_metadata(BatchContextSafeHandle ctx);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern int grpcsharp_batch_context_recv_close_on_server_cancelled(BatchContextSafeHandle ctx);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern void grpcsharp_batch_context_destroy(IntPtr ctx);
+ static readonly NativeMethods Native = NativeMethods.Get();
private BatchContextSafeHandle()
{
@@ -90,7 +50,7 @@ namespace Grpc.Core.Internal
public static BatchContextSafeHandle Create()
{
- return grpcsharp_batch_context_create();
+ return Native.grpcsharp_batch_context_create();
}
public IntPtr Handle
@@ -104,17 +64,17 @@ namespace Grpc.Core.Internal
// Gets data of recv_initial_metadata completion.
public Metadata GetReceivedInitialMetadata()
{
- IntPtr metadataArrayPtr = grpcsharp_batch_context_recv_initial_metadata(this);
+ IntPtr metadataArrayPtr = Native.grpcsharp_batch_context_recv_initial_metadata(this);
return MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr);
}
// Gets data of recv_status_on_client completion.
public ClientSideStatus GetReceivedStatusOnClient()
{
- string details = Marshal.PtrToStringAnsi(grpcsharp_batch_context_recv_status_on_client_details(this));
- var status = new Status(grpcsharp_batch_context_recv_status_on_client_status(this), details);
+ string details = Marshal.PtrToStringAnsi(Native.grpcsharp_batch_context_recv_status_on_client_details(this));
+ var status = new Status(Native.grpcsharp_batch_context_recv_status_on_client_status(this), details);
- IntPtr metadataArrayPtr = grpcsharp_batch_context_recv_status_on_client_trailing_metadata(this);
+ IntPtr metadataArrayPtr = Native.grpcsharp_batch_context_recv_status_on_client_trailing_metadata(this);
var metadata = MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr);
return new ClientSideStatus(status, metadata);
@@ -123,26 +83,26 @@ namespace Grpc.Core.Internal
// Gets data of recv_message completion.
public byte[] GetReceivedMessage()
{
- IntPtr len = grpcsharp_batch_context_recv_message_length(this);
+ IntPtr len = Native.grpcsharp_batch_context_recv_message_length(this);
if (len == new IntPtr(-1))
{
return null;
}
byte[] data = new byte[(int)len];
- grpcsharp_batch_context_recv_message_to_buffer(this, data, new UIntPtr((ulong)data.Length));
+ Native.grpcsharp_batch_context_recv_message_to_buffer(this, data, new UIntPtr((ulong)data.Length));
return data;
}
// Gets data of server_rpc_new completion.
public ServerRpcNew GetServerRpcNew(Server server)
{
- var call = grpcsharp_batch_context_server_rpc_new_call(this);
+ var call = Native.grpcsharp_batch_context_server_rpc_new_call(this);
- var method = Marshal.PtrToStringAnsi(grpcsharp_batch_context_server_rpc_new_method(this));
- var host = Marshal.PtrToStringAnsi(grpcsharp_batch_context_server_rpc_new_host(this));
- var deadline = grpcsharp_batch_context_server_rpc_new_deadline(this);
+ var method = Marshal.PtrToStringAnsi(Native.grpcsharp_batch_context_server_rpc_new_method(this));
+ var host = Marshal.PtrToStringAnsi(Native.grpcsharp_batch_context_server_rpc_new_host(this));
+ var deadline = Native.grpcsharp_batch_context_server_rpc_new_deadline(this);
- IntPtr metadataArrayPtr = grpcsharp_batch_context_server_rpc_new_request_metadata(this);
+ IntPtr metadataArrayPtr = Native.grpcsharp_batch_context_server_rpc_new_request_metadata(this);
var metadata = MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr);
return new ServerRpcNew(server, call, method, host, deadline, metadata);
@@ -151,12 +111,12 @@ namespace Grpc.Core.Internal
// Gets data of receive_close_on_server completion.
public bool GetReceivedCloseOnServerCancelled()
{
- return grpcsharp_batch_context_recv_close_on_server_cancelled(this) != 0;
+ return Native.grpcsharp_batch_context_recv_close_on_server_cancelled(this) != 0;
}
protected override bool ReleaseHandle()
{
- grpcsharp_batch_context_destroy(handle);
+ Native.grpcsharp_batch_context_destroy(handle);
return true;
}
}
diff --git a/src/csharp/Grpc.Core/Internal/CStringSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CStringSafeHandle.cs
index 92fbe8cf0f..0221798d2a 100644
--- a/src/csharp/Grpc.Core/Internal/CStringSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CStringSafeHandle.cs
@@ -39,8 +39,7 @@ namespace Grpc.Core.Internal
/// </summary>
internal class CStringSafeHandle : SafeHandleZeroIsInvalid
{
- [DllImport("grpc_csharp_ext.dll")]
- static extern void gprsharp_free(IntPtr ptr);
+ static readonly NativeMethods Native = NativeMethods.Get();
private CStringSafeHandle()
{
@@ -53,7 +52,7 @@ namespace Grpc.Core.Internal
protected override bool ReleaseHandle()
{
- gprsharp_free(handle);
+ Native.gprsharp_free(handle);
return true;
}
}
diff --git a/src/csharp/Grpc.Core/Internal/CallCredentialsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallCredentialsSafeHandle.cs
index 3678c7dd86..3095a34008 100644
--- a/src/csharp/Grpc.Core/Internal/CallCredentialsSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CallCredentialsSafeHandle.cs
@@ -40,11 +40,7 @@ namespace Grpc.Core.Internal
/// </summary>
internal class CallCredentialsSafeHandle : SafeHandleZeroIsInvalid
{
- [DllImport("grpc_csharp_ext.dll")]
- static extern CallCredentialsSafeHandle grpcsharp_composite_call_credentials_create(CallCredentialsSafeHandle creds1, CallCredentialsSafeHandle creds2);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern void grpcsharp_call_credentials_release(IntPtr credentials);
+ static readonly NativeMethods Native = NativeMethods.Get();
private CallCredentialsSafeHandle()
{
@@ -52,12 +48,12 @@ namespace Grpc.Core.Internal
public static CallCredentialsSafeHandle CreateComposite(CallCredentialsSafeHandle creds1, CallCredentialsSafeHandle creds2)
{
- return grpcsharp_composite_call_credentials_create(creds1, creds2);
+ return Native.grpcsharp_composite_call_credentials_create(creds1, creds2);
}
protected override bool ReleaseHandle()
{
- grpcsharp_call_credentials_release(handle);
+ Native.grpcsharp_call_credentials_release(handle);
return true;
}
}
diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
index 69dbdfea5e..454f88df08 100644
--- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
@@ -44,71 +44,12 @@ namespace Grpc.Core.Internal
internal class CallSafeHandle : SafeHandleZeroIsInvalid, INativeCall
{
public static readonly CallSafeHandle NullInstance = new CallSafeHandle();
+ static readonly NativeMethods Native = NativeMethods.Get();
const uint GRPC_WRITE_BUFFER_HINT = 1;
CompletionRegistry completionRegistry;
CompletionQueueSafeHandle completionQueue;
- [DllImport("grpc_csharp_ext.dll")]
- static extern GRPCCallError grpcsharp_call_cancel(CallSafeHandle call);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern GRPCCallError grpcsharp_call_cancel_with_status(CallSafeHandle call, StatusCode status, string description);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern GRPCCallError grpcsharp_call_start_unary(CallSafeHandle call,
- BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern GRPCCallError grpcsharp_call_start_client_streaming(CallSafeHandle call,
- BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern GRPCCallError grpcsharp_call_start_server_streaming(CallSafeHandle call,
- BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len,
- MetadataArraySafeHandle metadataArray, WriteFlags writeFlags);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern GRPCCallError grpcsharp_call_start_duplex_streaming(CallSafeHandle call,
- BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern GRPCCallError grpcsharp_call_send_message(CallSafeHandle call,
- BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len, WriteFlags writeFlags, bool sendEmptyInitialMetadata);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern GRPCCallError grpcsharp_call_send_close_from_client(CallSafeHandle call,
- BatchContextSafeHandle ctx);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern GRPCCallError grpcsharp_call_send_status_from_server(CallSafeHandle call,
- BatchContextSafeHandle ctx, StatusCode statusCode, string statusMessage, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern GRPCCallError grpcsharp_call_recv_message(CallSafeHandle call,
- BatchContextSafeHandle ctx);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern GRPCCallError grpcsharp_call_recv_initial_metadata(CallSafeHandle call,
- BatchContextSafeHandle ctx);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern GRPCCallError grpcsharp_call_start_serverside(CallSafeHandle call,
- BatchContextSafeHandle ctx);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern GRPCCallError grpcsharp_call_send_initial_metadata(CallSafeHandle call,
- BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern GRPCCallError grpcsharp_call_set_credentials(CallSafeHandle call, CallCredentialsSafeHandle credentials);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern CStringSafeHandle grpcsharp_call_get_peer(CallSafeHandle call);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern void grpcsharp_call_destroy(IntPtr call);
-
private CallSafeHandle()
{
}
@@ -121,7 +62,7 @@ namespace Grpc.Core.Internal
public void SetCredentials(CallCredentialsSafeHandle credentials)
{
- grpcsharp_call_set_credentials(this, credentials).CheckOk();
+ Native.grpcsharp_call_set_credentials(this, credentials).CheckOk();
}
public void StartUnary(UnaryResponseClientHandler callback, byte[] payload, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags)
@@ -130,7 +71,7 @@ namespace Grpc.Core.Internal
{
var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata()));
- grpcsharp_call_start_unary(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags)
+ Native.grpcsharp_call_start_unary(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags)
.CheckOk();
}
}
@@ -139,7 +80,7 @@ namespace Grpc.Core.Internal
{
using (Profilers.ForCurrentThread().NewScope("CallSafeHandle.StartUnary"))
{
- grpcsharp_call_start_unary(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags)
+ Native.grpcsharp_call_start_unary(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags)
.CheckOk();
}
}
@@ -150,7 +91,7 @@ namespace Grpc.Core.Internal
{
var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata()));
- grpcsharp_call_start_client_streaming(this, ctx, metadataArray).CheckOk();
+ Native.grpcsharp_call_start_client_streaming(this, ctx, metadataArray).CheckOk();
}
}
@@ -160,7 +101,7 @@ namespace Grpc.Core.Internal
{
var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient()));
- grpcsharp_call_start_server_streaming(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags).CheckOk();
+ Native.grpcsharp_call_start_server_streaming(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags).CheckOk();
}
}
@@ -170,7 +111,7 @@ namespace Grpc.Core.Internal
{
var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient()));
- grpcsharp_call_start_duplex_streaming(this, ctx, metadataArray).CheckOk();
+ Native.grpcsharp_call_start_duplex_streaming(this, ctx, metadataArray).CheckOk();
}
}
@@ -180,7 +121,7 @@ namespace Grpc.Core.Internal
{
var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
- grpcsharp_call_send_message(this, ctx, payload, new UIntPtr((ulong)payload.Length), writeFlags, sendEmptyInitialMetadata).CheckOk();
+ Native.grpcsharp_call_send_message(this, ctx, payload, new UIntPtr((ulong)payload.Length), writeFlags, sendEmptyInitialMetadata).CheckOk();
}
}
@@ -190,7 +131,7 @@ namespace Grpc.Core.Internal
{
var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
- grpcsharp_call_send_close_from_client(this, ctx).CheckOk();
+ Native.grpcsharp_call_send_close_from_client(this, ctx).CheckOk();
}
}
@@ -200,7 +141,7 @@ namespace Grpc.Core.Internal
{
var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
- grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, status.Detail, metadataArray, sendEmptyInitialMetadata).CheckOk();
+ Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, status.Detail, metadataArray, sendEmptyInitialMetadata).CheckOk();
}
}
@@ -210,7 +151,7 @@ namespace Grpc.Core.Internal
{
var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedMessage()));
- grpcsharp_call_recv_message(this, ctx).CheckOk();
+ Native.grpcsharp_call_recv_message(this, ctx).CheckOk();
}
}
@@ -220,7 +161,7 @@ namespace Grpc.Core.Internal
{
var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedInitialMetadata()));
- grpcsharp_call_recv_initial_metadata(this, ctx).CheckOk();
+ Native.grpcsharp_call_recv_initial_metadata(this, ctx).CheckOk();
}
}
@@ -230,7 +171,7 @@ namespace Grpc.Core.Internal
{
var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedCloseOnServerCancelled()));
- grpcsharp_call_start_serverside(this, ctx).CheckOk();
+ Native.grpcsharp_call_start_serverside(this, ctx).CheckOk();
}
}
@@ -240,23 +181,23 @@ namespace Grpc.Core.Internal
{
var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
- grpcsharp_call_send_initial_metadata(this, ctx, metadataArray).CheckOk();
+ Native.grpcsharp_call_send_initial_metadata(this, ctx, metadataArray).CheckOk();
}
}
public void Cancel()
{
- grpcsharp_call_cancel(this).CheckOk();
+ Native.grpcsharp_call_cancel(this).CheckOk();
}
public void CancelWithStatus(Status status)
{
- grpcsharp_call_cancel_with_status(this, status.StatusCode, status.Detail).CheckOk();
+ Native.grpcsharp_call_cancel_with_status(this, status.StatusCode, status.Detail).CheckOk();
}
public string GetPeer()
{
- using (var cstring = grpcsharp_call_get_peer(this))
+ using (var cstring = Native.grpcsharp_call_get_peer(this))
{
return cstring.GetValue();
}
@@ -264,7 +205,7 @@ namespace Grpc.Core.Internal
protected override bool ReleaseHandle()
{
- grpcsharp_call_destroy(handle);
+ Native.grpcsharp_call_destroy(handle);
return true;
}
diff --git a/src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs
index ea5b52374e..0038024245 100644
--- a/src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs
@@ -39,17 +39,7 @@ namespace Grpc.Core.Internal
/// </summary>
internal class ChannelArgsSafeHandle : SafeHandleZeroIsInvalid
{
- [DllImport("grpc_csharp_ext.dll")]
- static extern ChannelArgsSafeHandle grpcsharp_channel_args_create(UIntPtr numArgs);
-
- [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
- static extern void grpcsharp_channel_args_set_string(ChannelArgsSafeHandle args, UIntPtr index, string key, string value);
-
- [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
- static extern void grpcsharp_channel_args_set_integer(ChannelArgsSafeHandle args, UIntPtr index, string key, int value);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern void grpcsharp_channel_args_destroy(IntPtr args);
+ static readonly NativeMethods Native = NativeMethods.Get();
private ChannelArgsSafeHandle()
{
@@ -62,22 +52,22 @@ namespace Grpc.Core.Internal
public static ChannelArgsSafeHandle Create(int size)
{
- return grpcsharp_channel_args_create(new UIntPtr((uint)size));
+ return Native.grpcsharp_channel_args_create(new UIntPtr((uint)size));
}
public void SetString(int index, string key, string value)
{
- grpcsharp_channel_args_set_string(this, new UIntPtr((uint)index), key, value);
+ Native.grpcsharp_channel_args_set_string(this, new UIntPtr((uint)index), key, value);
}
public void SetInteger(int index, string key, int value)
{
- grpcsharp_channel_args_set_integer(this, new UIntPtr((uint)index), key, value);
+ Native.grpcsharp_channel_args_set_integer(this, new UIntPtr((uint)index), key, value);
}
protected override bool ReleaseHandle()
{
- grpcsharp_channel_args_destroy(handle);
+ Native.grpcsharp_channel_args_destroy(handle);
return true;
}
}
diff --git a/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs
index 8a58c64478..c85f55241a 100644
--- a/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs
@@ -40,14 +40,7 @@ namespace Grpc.Core.Internal
/// </summary>
internal class ChannelCredentialsSafeHandle : SafeHandleZeroIsInvalid
{
- [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
- static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern void grpcsharp_channel_credentials_release(IntPtr credentials);
+ static readonly NativeMethods Native = NativeMethods.Get();
private ChannelCredentialsSafeHandle()
{
@@ -64,22 +57,22 @@ namespace Grpc.Core.Internal
{
if (keyCertPair != null)
{
- return grpcsharp_ssl_credentials_create(pemRootCerts, keyCertPair.CertificateChain, keyCertPair.PrivateKey);
+ return Native.grpcsharp_ssl_credentials_create(pemRootCerts, keyCertPair.CertificateChain, keyCertPair.PrivateKey);
}
else
{
- return grpcsharp_ssl_credentials_create(pemRootCerts, null, null);
+ return Native.grpcsharp_ssl_credentials_create(pemRootCerts, null, null);
}
}
public static ChannelCredentialsSafeHandle CreateComposite(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds)
{
- return grpcsharp_composite_channel_credentials_create(channelCreds, callCreds);
+ return Native.grpcsharp_composite_channel_credentials_create(channelCreds, callCreds);
}
protected override bool ReleaseHandle()
{
- grpcsharp_channel_credentials_release(handle);
+ Native.grpcsharp_channel_credentials_release(handle);
return true;
}
}
diff --git a/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
index 4a5584121e..1dbd1f4e34 100644
--- a/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
@@ -41,27 +41,7 @@ namespace Grpc.Core.Internal
/// </summary>
internal class ChannelSafeHandle : SafeHandleZeroIsInvalid
{
- [DllImport("grpc_csharp_ext.dll")]
- static extern ChannelSafeHandle grpcsharp_insecure_channel_create(string target, ChannelArgsSafeHandle channelArgs);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern ChannelSafeHandle grpcsharp_secure_channel_create(ChannelCredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern CallSafeHandle grpcsharp_channel_create_call(ChannelSafeHandle channel, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern ChannelState grpcsharp_channel_check_connectivity_state(ChannelSafeHandle channel, int tryToConnect);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern void grpcsharp_channel_watch_connectivity_state(ChannelSafeHandle channel, ChannelState lastObservedState,
- Timespec deadline, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern CStringSafeHandle grpcsharp_channel_get_target(ChannelSafeHandle call);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern void grpcsharp_channel_destroy(IntPtr channel);
+ static readonly NativeMethods Native = NativeMethods.Get();
private ChannelSafeHandle()
{
@@ -72,7 +52,7 @@ namespace Grpc.Core.Internal
// Increment reference count for the native gRPC environment to make sure we don't do grpc_shutdown() before destroying the server handle.
// Doing so would make object finalizer crash if we end up abandoning the handle.
GrpcEnvironment.GrpcNativeInit();
- return grpcsharp_insecure_channel_create(target, channelArgs);
+ return Native.grpcsharp_insecure_channel_create(target, channelArgs);
}
public static ChannelSafeHandle CreateSecure(ChannelCredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs)
@@ -80,14 +60,14 @@ namespace Grpc.Core.Internal
// Increment reference count for the native gRPC environment to make sure we don't do grpc_shutdown() before destroying the server handle.
// Doing so would make object finalizer crash if we end up abandoning the handle.
GrpcEnvironment.GrpcNativeInit();
- return grpcsharp_secure_channel_create(credentials, target, channelArgs);
+ return Native.grpcsharp_secure_channel_create(credentials, target, channelArgs);
}
public CallSafeHandle CreateCall(CompletionRegistry registry, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline, CallCredentialsSafeHandle credentials)
{
using (Profilers.ForCurrentThread().NewScope("ChannelSafeHandle.CreateCall"))
{
- var result = grpcsharp_channel_create_call(this, parentCall, propagationMask, cq, method, host, deadline);
+ var result = Native.grpcsharp_channel_create_call(this, parentCall, propagationMask, cq, method, host, deadline);
if (credentials != null)
{
result.SetCredentials(credentials);
@@ -99,7 +79,7 @@ namespace Grpc.Core.Internal
public ChannelState CheckConnectivityState(bool tryToConnect)
{
- return grpcsharp_channel_check_connectivity_state(this, tryToConnect ? 1 : 0);
+ return Native.grpcsharp_channel_check_connectivity_state(this, tryToConnect ? 1 : 0);
}
public void WatchConnectivityState(ChannelState lastObservedState, Timespec deadline, CompletionQueueSafeHandle cq,
@@ -107,12 +87,12 @@ namespace Grpc.Core.Internal
{
var ctx = BatchContextSafeHandle.Create();
completionRegistry.RegisterBatchCompletion(ctx, callback);
- grpcsharp_channel_watch_connectivity_state(this, lastObservedState, deadline, cq, ctx);
+ Native.grpcsharp_channel_watch_connectivity_state(this, lastObservedState, deadline, cq, ctx);
}
public string GetTarget()
{
- using (var cstring = grpcsharp_channel_get_target(this))
+ using (var cstring = Native.grpcsharp_channel_get_target(this))
{
return cstring.GetValue();
}
@@ -120,7 +100,7 @@ namespace Grpc.Core.Internal
protected override bool ReleaseHandle()
{
- grpcsharp_channel_destroy(handle);
+ Native.grpcsharp_channel_destroy(handle);
GrpcEnvironment.GrpcNativeShutdown();
return true;
}
diff --git a/src/csharp/Grpc.Core/Internal/CompletionQueueEvent.cs b/src/csharp/Grpc.Core/Internal/CompletionQueueEvent.cs
index 3f517514a3..288680792a 100644
--- a/src/csharp/Grpc.Core/Internal/CompletionQueueEvent.cs
+++ b/src/csharp/Grpc.Core/Internal/CompletionQueueEvent.cs
@@ -42,8 +42,7 @@ namespace Grpc.Core.Internal
[StructLayout(LayoutKind.Sequential)]
internal struct CompletionQueueEvent
{
- [DllImport("grpc_csharp_ext.dll")]
- static extern int grpcsharp_sizeof_grpc_event();
+ static readonly NativeMethods Native = NativeMethods.Get();
public GRPCCompletionType type;
public int success;
@@ -53,7 +52,7 @@ namespace Grpc.Core.Internal
{
get
{
- return grpcsharp_sizeof_grpc_event();
+ return Native.grpcsharp_sizeof_grpc_event();
}
}
}
diff --git a/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs
index 3754ad382e..365de96fb7 100644
--- a/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs
@@ -42,22 +42,9 @@ namespace Grpc.Core.Internal
/// </summary>
internal class CompletionQueueSafeHandle : SafeHandleZeroIsInvalid
{
- AtomicCounter shutdownRefcount = new AtomicCounter(1);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern CompletionQueueSafeHandle grpcsharp_completion_queue_create();
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern void grpcsharp_completion_queue_shutdown(CompletionQueueSafeHandle cq);
+ static readonly NativeMethods Native = NativeMethods.Get();
- [DllImport("grpc_csharp_ext.dll")]
- static extern CompletionQueueEvent grpcsharp_completion_queue_next(CompletionQueueSafeHandle cq);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern CompletionQueueEvent grpcsharp_completion_queue_pluck(CompletionQueueSafeHandle cq, IntPtr tag);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern void grpcsharp_completion_queue_destroy(IntPtr cq);
+ AtomicCounter shutdownRefcount = new AtomicCounter(1);
private CompletionQueueSafeHandle()
{
@@ -65,20 +52,20 @@ namespace Grpc.Core.Internal
public static CompletionQueueSafeHandle Create()
{
- return grpcsharp_completion_queue_create();
+ return Native.grpcsharp_completion_queue_create();
}
public CompletionQueueEvent Next()
{
- return grpcsharp_completion_queue_next(this);
+ return Native.grpcsharp_completion_queue_next(this);
}
public CompletionQueueEvent Pluck(IntPtr tag)
{
using (Profilers.ForCurrentThread().NewScope("CompletionQueueSafeHandle.Pluck"))
{
- return grpcsharp_completion_queue_pluck(this, tag);
+ return Native.grpcsharp_completion_queue_pluck(this, tag);
}
}
@@ -98,7 +85,7 @@ namespace Grpc.Core.Internal
protected override bool ReleaseHandle()
{
- grpcsharp_completion_queue_destroy(handle);
+ Native.grpcsharp_completion_queue_destroy(handle);
return true;
}
@@ -106,7 +93,7 @@ namespace Grpc.Core.Internal
{
if (shutdownRefcount.Decrement() == 0)
{
- grpcsharp_completion_queue_shutdown(this);
+ Native.grpcsharp_completion_queue_shutdown(this);
}
}
diff --git a/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs b/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs
index ed1bd24498..25735d5262 100644
--- a/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/MetadataArraySafeHandle.cs
@@ -40,26 +40,7 @@ namespace Grpc.Core.Internal
/// </summary>
internal class MetadataArraySafeHandle : SafeHandleZeroIsInvalid
{
- [DllImport("grpc_csharp_ext.dll")]
- static extern MetadataArraySafeHandle grpcsharp_metadata_array_create(UIntPtr capacity);
-
- [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
- static extern void grpcsharp_metadata_array_add(MetadataArraySafeHandle array, string key, byte[] value, UIntPtr valueLength);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern UIntPtr grpcsharp_metadata_array_count(IntPtr metadataArray);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern IntPtr grpcsharp_metadata_array_get_key(IntPtr metadataArray, UIntPtr index);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern IntPtr grpcsharp_metadata_array_get_value(IntPtr metadataArray, UIntPtr index);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern UIntPtr grpcsharp_metadata_array_get_value_length(IntPtr metadataArray, UIntPtr index);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern void grpcsharp_metadata_array_destroy_full(IntPtr array);
+ static readonly NativeMethods Native = NativeMethods.Get();
private MetadataArraySafeHandle()
{
@@ -70,11 +51,11 @@ namespace Grpc.Core.Internal
using (Profilers.ForCurrentThread().NewScope("MetadataArraySafeHandle.Create"))
{
// TODO(jtattermusch): we might wanna check that the metadata is readonly
- var metadataArray = grpcsharp_metadata_array_create(new UIntPtr((ulong)metadata.Count));
+ var metadataArray = Native.grpcsharp_metadata_array_create(new UIntPtr((ulong)metadata.Count));
for (int i = 0; i < metadata.Count; i++)
{
var valueBytes = metadata[i].GetSerializedValueUnsafe();
- grpcsharp_metadata_array_add(metadataArray, metadata[i].Key, valueBytes, new UIntPtr((ulong)valueBytes.Length));
+ Native.grpcsharp_metadata_array_add(metadataArray, metadata[i].Key, valueBytes, new UIntPtr((ulong)valueBytes.Length));
}
return metadataArray;
}
@@ -90,15 +71,15 @@ namespace Grpc.Core.Internal
return null;
}
- ulong count = grpcsharp_metadata_array_count(metadataArray).ToUInt64();
+ ulong count = Native.grpcsharp_metadata_array_count(metadataArray).ToUInt64();
var metadata = new Metadata();
for (ulong i = 0; i < count; i++)
{
var index = new UIntPtr(i);
- string key = Marshal.PtrToStringAnsi(grpcsharp_metadata_array_get_key(metadataArray, index));
- var bytes = new byte[grpcsharp_metadata_array_get_value_length(metadataArray, index).ToUInt64()];
- Marshal.Copy(grpcsharp_metadata_array_get_value(metadataArray, index), bytes, 0, bytes.Length);
+ string key = Marshal.PtrToStringAnsi(Native.grpcsharp_metadata_array_get_key(metadataArray, index));
+ var bytes = new byte[Native.grpcsharp_metadata_array_get_value_length(metadataArray, index).ToUInt64()];
+ Marshal.Copy(Native.grpcsharp_metadata_array_get_value(metadataArray, index), bytes, 0, bytes.Length);
metadata.Add(Metadata.Entry.CreateUnsafe(key, bytes));
}
return metadata;
@@ -114,7 +95,7 @@ namespace Grpc.Core.Internal
protected override bool ReleaseHandle()
{
- grpcsharp_metadata_array_destroy_full(handle);
+ Native.grpcsharp_metadata_array_destroy_full(handle);
return true;
}
}
diff --git a/src/csharp/Grpc.Core/Internal/NativeExtension.cs b/src/csharp/Grpc.Core/Internal/NativeExtension.cs
new file mode 100644
index 0000000000..3a4ebf9c4e
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/NativeExtension.cs
@@ -0,0 +1,158 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.IO;
+using System.Reflection;
+
+using Grpc.Core.Logging;
+
+namespace Grpc.Core.Internal
+{
+ /// <summary>
+ /// Takes care of loading C# native extension and provides access to PInvoke calls the library exports.
+ /// </summary>
+ internal sealed class NativeExtension
+ {
+ const string NativeLibrariesDir = "nativelibs";
+
+ static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<NativeExtension>();
+ static readonly object staticLock = new object();
+ static volatile NativeExtension instance;
+
+ readonly NativeMethods nativeMethods;
+
+ private NativeExtension()
+ {
+ this.nativeMethods = new NativeMethods(Load());
+
+ // Redirect the the native logs as the very first thing after loading the native extension
+ // to make sure we don't lose any logs.
+ NativeLogRedirector.Redirect(this.nativeMethods);
+
+ Logger.Debug("gRPC native library loaded successfully.");
+ }
+
+ /// <summary>
+ /// Gets singleton instance of this class.
+ /// The native extension is loaded when called for the first time.
+ /// </summary>
+ public static NativeExtension Get()
+ {
+ if (instance == null)
+ {
+ lock (staticLock)
+ {
+ if (instance == null) {
+ instance = new NativeExtension();
+ }
+ }
+ }
+ return instance;
+ }
+
+ /// <summary>
+ /// Provides access to the exported native methods.
+ /// </summary>
+ public NativeMethods NativeMethods
+ {
+ get { return this.nativeMethods; }
+ }
+
+ /// <summary>
+ /// Detects which configuration of native extension to load and load it.
+ /// </summary>
+ private static UnmanagedLibrary Load()
+ {
+ // TODO: allow customizing path to native extension (possibly through exposing a GrpcEnvironment property).
+
+ var libraryFlavor = string.Format("{0}_{1}", GetPlatformString(), GetArchitectureString());
+ var fullPath = Path.Combine(GetExecutingAssemblyDirectory(),
+ NativeLibrariesDir, libraryFlavor, GetNativeLibraryFilename());
+ return new UnmanagedLibrary(fullPath);
+ }
+
+ private static string GetExecutingAssemblyDirectory()
+ {
+ return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
+ }
+
+ private static string GetPlatformString()
+ {
+ if (PlatformApis.IsWindows)
+ {
+ return "windows";
+ }
+ if (PlatformApis.IsLinux)
+ {
+ return "linux";
+ }
+ if (PlatformApis.IsMacOSX)
+ {
+ return "macosx";
+ }
+ throw new InvalidOperationException("Unsupported platform.");
+ }
+
+ // Currently, only Intel platform is supported.
+ private static string GetArchitectureString()
+ {
+ if (PlatformApis.Is64Bit)
+ {
+ return "x64";
+ }
+ else
+ {
+ return "x86";
+ }
+ }
+
+ // platform specific file name of the extension library
+ private static string GetNativeLibraryFilename()
+ {
+ if (PlatformApis.IsWindows)
+ {
+ return "grpc_csharp_ext.dll";
+ }
+ if (PlatformApis.IsLinux)
+ {
+ return "libgrpc_csharp_ext.so";
+ }
+ if (PlatformApis.IsMacOSX)
+ {
+ return "libgrpc_csharp_ext.dylib";
+ }
+ throw new InvalidOperationException("Unsupported platform.");
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs b/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs
index b8a55c5fe8..3fcf8673ee 100644
--- a/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs
@@ -51,20 +51,17 @@ namespace Grpc.Core.Internal
static object staticLock = new object();
static GprLogDelegate writeCallback;
- [DllImport("grpc_csharp_ext.dll")]
- static extern void grpcsharp_redirect_log(GprLogDelegate callback);
-
/// <summary>
/// Redirects logs from native gRPC C core library to a general logger.
/// </summary>
- public static void Redirect()
+ public static void Redirect(NativeMethods native)
{
lock (staticLock)
{
if (writeCallback == null)
{
writeCallback = new GprLogDelegate(HandleWrite);
- grpcsharp_redirect_log(writeCallback);
+ native.grpcsharp_redirect_log(writeCallback);
}
}
}
diff --git a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs
index 8bb646d303..ab9b8e96a4 100644
--- a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs
@@ -44,12 +44,7 @@ namespace Grpc.Core.Internal
{
const string GetMetadataExceptionMsg = "Exception occured in metadata credentials plugin.";
static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<NativeMetadataCredentialsPlugin>();
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(NativeMetadataInterceptor interceptor);
-
- [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
- static extern void grpcsharp_metadata_credentials_notify_from_plugin(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails);
+ static readonly NativeMethods Native = NativeMethods.Get();
AsyncAuthInterceptor interceptor;
GCHandle gcHandle;
@@ -63,7 +58,7 @@ namespace Grpc.Core.Internal
// Make sure the callback doesn't get garbage collected until it is destroyed.
this.gcHandle = GCHandle.Alloc(this.nativeInterceptor, GCHandleType.Normal);
- this.credentials = grpcsharp_metadata_credentials_create_from_plugin(nativeInterceptor);
+ this.credentials = Native.grpcsharp_metadata_credentials_create_from_plugin(nativeInterceptor);
}
public CallCredentialsSafeHandle Credentials
@@ -87,7 +82,7 @@ namespace Grpc.Core.Internal
}
catch (Exception e)
{
- grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, MetadataArraySafeHandle.Create(Metadata.Empty), StatusCode.Unknown, GetMetadataExceptionMsg);
+ Native.grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, MetadataArraySafeHandle.Create(Metadata.Empty), StatusCode.Unknown, GetMetadataExceptionMsg);
Logger.Error(e, GetMetadataExceptionMsg);
}
}
@@ -101,12 +96,12 @@ namespace Grpc.Core.Internal
using (var metadataArray = MetadataArraySafeHandle.Create(metadata))
{
- grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, metadataArray, StatusCode.OK, null);
+ Native.grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, metadataArray, StatusCode.OK, null);
}
}
catch (Exception e)
{
- grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, MetadataArraySafeHandle.Create(Metadata.Empty), StatusCode.Unknown, GetMetadataExceptionMsg);
+ Native.grpcsharp_metadata_credentials_notify_from_plugin(callbackPtr, userDataPtr, MetadataArraySafeHandle.Create(Metadata.Empty), StatusCode.Unknown, GetMetadataExceptionMsg);
Logger.Error(e, GetMetadataExceptionMsg);
}
}
diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.cs
new file mode 100644
index 0000000000..b79d7c7565
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/NativeMethods.cs
@@ -0,0 +1,816 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Concurrent;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+using Grpc.Core.Logging;
+using Grpc.Core.Utils;
+
+namespace Grpc.Core.Internal
+{
+ /// <summary>
+ /// Provides access to all native methods provided by <c>NativeExtension</c>.
+ /// An extra level of indirection is added to P/Invoke calls to allow intelligent loading
+ /// of the right configuration of the native extension based on current platform, architecture etc.
+ /// </summary>
+ internal class NativeMethods
+ {
+ #region Native methods
+
+ public readonly Delegates.grpcsharp_init_delegate grpcsharp_init;
+ public readonly Delegates.grpcsharp_shutdown_delegate grpcsharp_shutdown;
+ public readonly Delegates.grpcsharp_version_string_delegate grpcsharp_version_string;
+
+ public readonly Delegates.grpcsharp_batch_context_create_delegate grpcsharp_batch_context_create;
+ public readonly Delegates.grpcsharp_batch_context_recv_initial_metadata_delegate grpcsharp_batch_context_recv_initial_metadata;
+ public readonly Delegates.grpcsharp_batch_context_recv_message_length_delegate grpcsharp_batch_context_recv_message_length;
+ public readonly Delegates.grpcsharp_batch_context_recv_message_to_buffer_delegate grpcsharp_batch_context_recv_message_to_buffer;
+ public readonly Delegates.grpcsharp_batch_context_recv_status_on_client_status_delegate grpcsharp_batch_context_recv_status_on_client_status;
+ public readonly Delegates.grpcsharp_batch_context_recv_status_on_client_details_delegate grpcsharp_batch_context_recv_status_on_client_details;
+ public readonly Delegates.grpcsharp_batch_context_recv_status_on_client_trailing_metadata_delegate grpcsharp_batch_context_recv_status_on_client_trailing_metadata;
+ public readonly Delegates.grpcsharp_batch_context_server_rpc_new_call_delegate grpcsharp_batch_context_server_rpc_new_call;
+ public readonly Delegates.grpcsharp_batch_context_server_rpc_new_method_delegate grpcsharp_batch_context_server_rpc_new_method;
+ public readonly Delegates.grpcsharp_batch_context_server_rpc_new_host_delegate grpcsharp_batch_context_server_rpc_new_host;
+ public readonly Delegates.grpcsharp_batch_context_server_rpc_new_deadline_delegate grpcsharp_batch_context_server_rpc_new_deadline;
+ public readonly Delegates.grpcsharp_batch_context_server_rpc_new_request_metadata_delegate grpcsharp_batch_context_server_rpc_new_request_metadata;
+ public readonly Delegates.grpcsharp_batch_context_recv_close_on_server_cancelled_delegate grpcsharp_batch_context_recv_close_on_server_cancelled;
+ public readonly Delegates.grpcsharp_batch_context_destroy_delegate grpcsharp_batch_context_destroy;
+
+ public readonly Delegates.grpcsharp_composite_call_credentials_create_delegate grpcsharp_composite_call_credentials_create;
+ public readonly Delegates.grpcsharp_call_credentials_release_delegate grpcsharp_call_credentials_release;
+
+ public readonly Delegates.grpcsharp_call_cancel_delegate grpcsharp_call_cancel;
+ public readonly Delegates.grpcsharp_call_cancel_with_status_delegate grpcsharp_call_cancel_with_status;
+ public readonly Delegates.grpcsharp_call_start_unary_delegate grpcsharp_call_start_unary;
+ public readonly Delegates.grpcsharp_call_start_client_streaming_delegate grpcsharp_call_start_client_streaming;
+ public readonly Delegates.grpcsharp_call_start_server_streaming_delegate grpcsharp_call_start_server_streaming;
+ public readonly Delegates.grpcsharp_call_start_duplex_streaming_delegate grpcsharp_call_start_duplex_streaming;
+ public readonly Delegates.grpcsharp_call_send_message_delegate grpcsharp_call_send_message;
+ public readonly Delegates.grpcsharp_call_send_close_from_client_delegate grpcsharp_call_send_close_from_client;
+ public readonly Delegates.grpcsharp_call_send_status_from_server_delegate grpcsharp_call_send_status_from_server;
+ public readonly Delegates.grpcsharp_call_recv_message_delegate grpcsharp_call_recv_message;
+ public readonly Delegates.grpcsharp_call_recv_initial_metadata_delegate grpcsharp_call_recv_initial_metadata;
+ public readonly Delegates.grpcsharp_call_start_serverside_delegate grpcsharp_call_start_serverside;
+ public readonly Delegates.grpcsharp_call_send_initial_metadata_delegate grpcsharp_call_send_initial_metadata;
+ public readonly Delegates.grpcsharp_call_set_credentials_delegate grpcsharp_call_set_credentials;
+ public readonly Delegates.grpcsharp_call_get_peer_delegate grpcsharp_call_get_peer;
+ public readonly Delegates.grpcsharp_call_destroy_delegate grpcsharp_call_destroy;
+
+ public readonly Delegates.grpcsharp_channel_args_create_delegate grpcsharp_channel_args_create;
+ public readonly Delegates.grpcsharp_channel_args_set_string_delegate grpcsharp_channel_args_set_string;
+ public readonly Delegates.grpcsharp_channel_args_set_integer_delegate grpcsharp_channel_args_set_integer;
+ public readonly Delegates.grpcsharp_channel_args_destroy_delegate grpcsharp_channel_args_destroy;
+
+ public readonly Delegates.grpcsharp_ssl_credentials_create_delegate grpcsharp_ssl_credentials_create;
+ public readonly Delegates.grpcsharp_composite_channel_credentials_create_delegate grpcsharp_composite_channel_credentials_create;
+ public readonly Delegates.grpcsharp_channel_credentials_release_delegate grpcsharp_channel_credentials_release;
+
+ public readonly Delegates.grpcsharp_insecure_channel_create_delegate grpcsharp_insecure_channel_create;
+ public readonly Delegates.grpcsharp_secure_channel_create_delegate grpcsharp_secure_channel_create;
+ public readonly Delegates.grpcsharp_channel_create_call_delegate grpcsharp_channel_create_call;
+ public readonly Delegates.grpcsharp_channel_check_connectivity_state_delegate grpcsharp_channel_check_connectivity_state;
+ public readonly Delegates.grpcsharp_channel_watch_connectivity_state_delegate grpcsharp_channel_watch_connectivity_state;
+ public readonly Delegates.grpcsharp_channel_get_target_delegate grpcsharp_channel_get_target;
+ public readonly Delegates.grpcsharp_channel_destroy_delegate grpcsharp_channel_destroy;
+
+ public readonly Delegates.grpcsharp_sizeof_grpc_event_delegate grpcsharp_sizeof_grpc_event;
+
+ public readonly Delegates.grpcsharp_completion_queue_create_delegate grpcsharp_completion_queue_create;
+ public readonly Delegates.grpcsharp_completion_queue_shutdown_delegate grpcsharp_completion_queue_shutdown;
+ public readonly Delegates.grpcsharp_completion_queue_next_delegate grpcsharp_completion_queue_next;
+ public readonly Delegates.grpcsharp_completion_queue_pluck_delegate grpcsharp_completion_queue_pluck;
+ public readonly Delegates.grpcsharp_completion_queue_destroy_delegate grpcsharp_completion_queue_destroy;
+
+ public readonly Delegates.gprsharp_free_delegate gprsharp_free;
+
+ public readonly Delegates.grpcsharp_metadata_array_create_delegate grpcsharp_metadata_array_create;
+ public readonly Delegates.grpcsharp_metadata_array_add_delegate grpcsharp_metadata_array_add;
+ public readonly Delegates.grpcsharp_metadata_array_count_delegate grpcsharp_metadata_array_count;
+ public readonly Delegates.grpcsharp_metadata_array_get_key_delegate grpcsharp_metadata_array_get_key;
+ public readonly Delegates.grpcsharp_metadata_array_get_value_delegate grpcsharp_metadata_array_get_value;
+ public readonly Delegates.grpcsharp_metadata_array_get_value_length_delegate grpcsharp_metadata_array_get_value_length;
+ public readonly Delegates.grpcsharp_metadata_array_destroy_full_delegate grpcsharp_metadata_array_destroy_full;
+
+ public readonly Delegates.grpcsharp_redirect_log_delegate grpcsharp_redirect_log;
+
+ public readonly Delegates.grpcsharp_metadata_credentials_create_from_plugin_delegate grpcsharp_metadata_credentials_create_from_plugin;
+ public readonly Delegates.grpcsharp_metadata_credentials_notify_from_plugin_delegate grpcsharp_metadata_credentials_notify_from_plugin;
+
+ public readonly Delegates.grpcsharp_ssl_server_credentials_create_delegate grpcsharp_ssl_server_credentials_create;
+ public readonly Delegates.grpcsharp_server_credentials_release_delegate grpcsharp_server_credentials_release;
+
+ public readonly Delegates.grpcsharp_server_create_delegate grpcsharp_server_create;
+ public readonly Delegates.grpcsharp_server_add_insecure_http2_port_delegate grpcsharp_server_add_insecure_http2_port;
+ public readonly Delegates.grpcsharp_server_add_secure_http2_port_delegate grpcsharp_server_add_secure_http2_port;
+ public readonly Delegates.grpcsharp_server_start_delegate grpcsharp_server_start;
+ public readonly Delegates.grpcsharp_server_request_call_delegate grpcsharp_server_request_call;
+ public readonly Delegates.grpcsharp_server_cancel_all_calls_delegate grpcsharp_server_cancel_all_calls;
+ public readonly Delegates.grpcsharp_server_shutdown_and_notify_callback_delegate grpcsharp_server_shutdown_and_notify_callback;
+ public readonly Delegates.grpcsharp_server_destroy_delegate grpcsharp_server_destroy;
+
+ public readonly Delegates.gprsharp_now_delegate gprsharp_now;
+ public readonly Delegates.gprsharp_inf_future_delegate gprsharp_inf_future;
+ public readonly Delegates.gprsharp_inf_past_delegate gprsharp_inf_past;
+ public readonly Delegates.gprsharp_convert_clock_type_delegate gprsharp_convert_clock_type;
+ public readonly Delegates.gprsharp_sizeof_timespec_delegate gprsharp_sizeof_timespec;
+
+ public readonly Delegates.grpcsharp_test_callback_delegate grpcsharp_test_callback;
+ public readonly Delegates.grpcsharp_test_nop_delegate grpcsharp_test_nop;
+
+ #endregion
+
+ public NativeMethods(UnmanagedLibrary library)
+ {
+ if (PlatformApis.IsLinux || PlatformApis.IsMacOSX)
+ {
+ this.grpcsharp_init = GetMethodDelegate<Delegates.grpcsharp_init_delegate>(library);
+ this.grpcsharp_shutdown = GetMethodDelegate<Delegates.grpcsharp_shutdown_delegate>(library);
+ this.grpcsharp_version_string = GetMethodDelegate<Delegates.grpcsharp_version_string_delegate>(library);
+
+ this.grpcsharp_batch_context_create = GetMethodDelegate<Delegates.grpcsharp_batch_context_create_delegate>(library);
+ this.grpcsharp_batch_context_recv_initial_metadata = GetMethodDelegate<Delegates.grpcsharp_batch_context_recv_initial_metadata_delegate>(library);
+ this.grpcsharp_batch_context_recv_message_length = GetMethodDelegate<Delegates.grpcsharp_batch_context_recv_message_length_delegate>(library);
+ this.grpcsharp_batch_context_recv_message_to_buffer = GetMethodDelegate<Delegates.grpcsharp_batch_context_recv_message_to_buffer_delegate>(library);
+ this.grpcsharp_batch_context_recv_status_on_client_status = GetMethodDelegate<Delegates.grpcsharp_batch_context_recv_status_on_client_status_delegate>(library);
+ this.grpcsharp_batch_context_recv_status_on_client_details = GetMethodDelegate<Delegates.grpcsharp_batch_context_recv_status_on_client_details_delegate>(library);
+ this.grpcsharp_batch_context_recv_status_on_client_trailing_metadata = GetMethodDelegate<Delegates.grpcsharp_batch_context_recv_status_on_client_trailing_metadata_delegate>(library);
+ this.grpcsharp_batch_context_server_rpc_new_call = GetMethodDelegate<Delegates.grpcsharp_batch_context_server_rpc_new_call_delegate>(library);
+ this.grpcsharp_batch_context_server_rpc_new_method = GetMethodDelegate<Delegates.grpcsharp_batch_context_server_rpc_new_method_delegate>(library);
+ this.grpcsharp_batch_context_server_rpc_new_host = GetMethodDelegate<Delegates.grpcsharp_batch_context_server_rpc_new_host_delegate>(library);
+ this.grpcsharp_batch_context_server_rpc_new_deadline = GetMethodDelegate<Delegates.grpcsharp_batch_context_server_rpc_new_deadline_delegate>(library);
+ this.grpcsharp_batch_context_server_rpc_new_request_metadata = GetMethodDelegate<Delegates.grpcsharp_batch_context_server_rpc_new_request_metadata_delegate>(library);
+ this.grpcsharp_batch_context_recv_close_on_server_cancelled = GetMethodDelegate<Delegates.grpcsharp_batch_context_recv_close_on_server_cancelled_delegate>(library);
+ this.grpcsharp_batch_context_destroy = GetMethodDelegate<Delegates.grpcsharp_batch_context_destroy_delegate>(library);
+
+ this.grpcsharp_composite_call_credentials_create = GetMethodDelegate<Delegates.grpcsharp_composite_call_credentials_create_delegate>(library);
+ this.grpcsharp_call_credentials_release = GetMethodDelegate<Delegates.grpcsharp_call_credentials_release_delegate>(library);
+
+ this.grpcsharp_call_cancel = GetMethodDelegate<Delegates.grpcsharp_call_cancel_delegate>(library);
+ this.grpcsharp_call_cancel_with_status = GetMethodDelegate<Delegates.grpcsharp_call_cancel_with_status_delegate>(library);
+ this.grpcsharp_call_start_unary = GetMethodDelegate<Delegates.grpcsharp_call_start_unary_delegate>(library);
+ this.grpcsharp_call_start_client_streaming = GetMethodDelegate<Delegates.grpcsharp_call_start_client_streaming_delegate>(library);
+ this.grpcsharp_call_start_server_streaming = GetMethodDelegate<Delegates.grpcsharp_call_start_server_streaming_delegate>(library);
+ this.grpcsharp_call_start_duplex_streaming = GetMethodDelegate<Delegates.grpcsharp_call_start_duplex_streaming_delegate>(library);
+ this.grpcsharp_call_send_message = GetMethodDelegate<Delegates.grpcsharp_call_send_message_delegate>(library);
+ this.grpcsharp_call_send_close_from_client = GetMethodDelegate<Delegates.grpcsharp_call_send_close_from_client_delegate>(library);
+ this.grpcsharp_call_send_status_from_server = GetMethodDelegate<Delegates.grpcsharp_call_send_status_from_server_delegate>(library);
+ this.grpcsharp_call_recv_message = GetMethodDelegate<Delegates.grpcsharp_call_recv_message_delegate>(library);
+ this.grpcsharp_call_recv_initial_metadata = GetMethodDelegate<Delegates.grpcsharp_call_recv_initial_metadata_delegate>(library);
+ this.grpcsharp_call_start_serverside = GetMethodDelegate<Delegates.grpcsharp_call_start_serverside_delegate>(library);
+ this.grpcsharp_call_send_initial_metadata = GetMethodDelegate<Delegates.grpcsharp_call_send_initial_metadata_delegate>(library);
+ this.grpcsharp_call_set_credentials = GetMethodDelegate<Delegates.grpcsharp_call_set_credentials_delegate>(library);
+ this.grpcsharp_call_get_peer = GetMethodDelegate<Delegates.grpcsharp_call_get_peer_delegate>(library);
+ this.grpcsharp_call_destroy = GetMethodDelegate<Delegates.grpcsharp_call_destroy_delegate>(library);
+
+ this.grpcsharp_channel_args_create = GetMethodDelegate<Delegates.grpcsharp_channel_args_create_delegate>(library);
+ this.grpcsharp_channel_args_set_string = GetMethodDelegate<Delegates.grpcsharp_channel_args_set_string_delegate>(library);
+ this.grpcsharp_channel_args_set_integer = GetMethodDelegate<Delegates.grpcsharp_channel_args_set_integer_delegate>(library);
+ this.grpcsharp_channel_args_destroy = GetMethodDelegate<Delegates.grpcsharp_channel_args_destroy_delegate>(library);
+
+ this.grpcsharp_ssl_credentials_create = GetMethodDelegate<Delegates.grpcsharp_ssl_credentials_create_delegate>(library);
+ this.grpcsharp_composite_channel_credentials_create = GetMethodDelegate<Delegates.grpcsharp_composite_channel_credentials_create_delegate>(library);
+ this.grpcsharp_channel_credentials_release = GetMethodDelegate<Delegates.grpcsharp_channel_credentials_release_delegate>(library);
+
+ this.grpcsharp_insecure_channel_create = GetMethodDelegate<Delegates.grpcsharp_insecure_channel_create_delegate>(library);
+ this.grpcsharp_secure_channel_create = GetMethodDelegate<Delegates.grpcsharp_secure_channel_create_delegate>(library);
+ this.grpcsharp_channel_create_call = GetMethodDelegate<Delegates.grpcsharp_channel_create_call_delegate>(library);
+ this.grpcsharp_channel_check_connectivity_state = GetMethodDelegate<Delegates.grpcsharp_channel_check_connectivity_state_delegate>(library);
+ this.grpcsharp_channel_watch_connectivity_state = GetMethodDelegate<Delegates.grpcsharp_channel_watch_connectivity_state_delegate>(library);
+ this.grpcsharp_channel_get_target = GetMethodDelegate<Delegates.grpcsharp_channel_get_target_delegate>(library);
+ this.grpcsharp_channel_destroy = GetMethodDelegate<Delegates.grpcsharp_channel_destroy_delegate>(library);
+
+ this.grpcsharp_sizeof_grpc_event = GetMethodDelegate<Delegates.grpcsharp_sizeof_grpc_event_delegate>(library);
+
+ this.grpcsharp_completion_queue_create = GetMethodDelegate<Delegates.grpcsharp_completion_queue_create_delegate>(library);
+ this.grpcsharp_completion_queue_shutdown = GetMethodDelegate<Delegates.grpcsharp_completion_queue_shutdown_delegate>(library);
+ this.grpcsharp_completion_queue_next = GetMethodDelegate<Delegates.grpcsharp_completion_queue_next_delegate>(library);
+ this.grpcsharp_completion_queue_pluck = GetMethodDelegate<Delegates.grpcsharp_completion_queue_pluck_delegate>(library);
+ this.grpcsharp_completion_queue_destroy = GetMethodDelegate<Delegates.grpcsharp_completion_queue_destroy_delegate>(library);
+
+ this.gprsharp_free = GetMethodDelegate<Delegates.gprsharp_free_delegate>(library);
+
+ this.grpcsharp_metadata_array_create = GetMethodDelegate<Delegates.grpcsharp_metadata_array_create_delegate>(library);
+ this.grpcsharp_metadata_array_add = GetMethodDelegate<Delegates.grpcsharp_metadata_array_add_delegate>(library);
+ this.grpcsharp_metadata_array_count = GetMethodDelegate<Delegates.grpcsharp_metadata_array_count_delegate>(library);
+ this.grpcsharp_metadata_array_get_key = GetMethodDelegate<Delegates.grpcsharp_metadata_array_get_key_delegate>(library);
+ this.grpcsharp_metadata_array_get_value = GetMethodDelegate<Delegates.grpcsharp_metadata_array_get_value_delegate>(library);
+ this.grpcsharp_metadata_array_get_value_length = GetMethodDelegate<Delegates.grpcsharp_metadata_array_get_value_length_delegate>(library);
+ this.grpcsharp_metadata_array_destroy_full = GetMethodDelegate<Delegates.grpcsharp_metadata_array_destroy_full_delegate>(library);
+
+ this.grpcsharp_redirect_log = GetMethodDelegate<Delegates.grpcsharp_redirect_log_delegate>(library);
+
+ this.grpcsharp_metadata_credentials_create_from_plugin = GetMethodDelegate<Delegates.grpcsharp_metadata_credentials_create_from_plugin_delegate>(library);
+ this.grpcsharp_metadata_credentials_notify_from_plugin = GetMethodDelegate<Delegates.grpcsharp_metadata_credentials_notify_from_plugin_delegate>(library);
+
+ this.grpcsharp_ssl_server_credentials_create = GetMethodDelegate<Delegates.grpcsharp_ssl_server_credentials_create_delegate>(library);
+ this.grpcsharp_server_credentials_release = GetMethodDelegate<Delegates.grpcsharp_server_credentials_release_delegate>(library);
+
+ this.grpcsharp_server_create = GetMethodDelegate<Delegates.grpcsharp_server_create_delegate>(library);
+ this.grpcsharp_server_add_insecure_http2_port = GetMethodDelegate<Delegates.grpcsharp_server_add_insecure_http2_port_delegate>(library);
+ this.grpcsharp_server_add_secure_http2_port = GetMethodDelegate<Delegates.grpcsharp_server_add_secure_http2_port_delegate>(library);
+ this.grpcsharp_server_start = GetMethodDelegate<Delegates.grpcsharp_server_start_delegate>(library);
+ this.grpcsharp_server_request_call = GetMethodDelegate<Delegates.grpcsharp_server_request_call_delegate>(library);
+ this.grpcsharp_server_cancel_all_calls = GetMethodDelegate<Delegates.grpcsharp_server_cancel_all_calls_delegate>(library);
+ this.grpcsharp_server_shutdown_and_notify_callback = GetMethodDelegate<Delegates.grpcsharp_server_shutdown_and_notify_callback_delegate>(library);
+ this.grpcsharp_server_destroy = GetMethodDelegate<Delegates.grpcsharp_server_destroy_delegate>(library);
+
+ this.gprsharp_now = GetMethodDelegate<Delegates.gprsharp_now_delegate>(library);
+ this.gprsharp_inf_future = GetMethodDelegate<Delegates.gprsharp_inf_future_delegate>(library);
+ this.gprsharp_inf_past = GetMethodDelegate<Delegates.gprsharp_inf_past_delegate>(library);
+ this.gprsharp_convert_clock_type = GetMethodDelegate<Delegates.gprsharp_convert_clock_type_delegate>(library);
+ this.gprsharp_sizeof_timespec = GetMethodDelegate<Delegates.gprsharp_sizeof_timespec_delegate>(library);
+
+ this.grpcsharp_test_callback = GetMethodDelegate<Delegates.grpcsharp_test_callback_delegate>(library);
+ this.grpcsharp_test_nop = GetMethodDelegate<Delegates.grpcsharp_test_nop_delegate>(library);
+ }
+ else
+ {
+ // Windows or fallback
+ this.grpcsharp_init = PInvokeMethods.grpcsharp_init;
+ this.grpcsharp_shutdown = PInvokeMethods.grpcsharp_shutdown;
+ this.grpcsharp_version_string = PInvokeMethods.grpcsharp_version_string;
+
+ this.grpcsharp_batch_context_create = PInvokeMethods.grpcsharp_batch_context_create;
+ this.grpcsharp_batch_context_recv_initial_metadata = PInvokeMethods.grpcsharp_batch_context_recv_initial_metadata;
+ this.grpcsharp_batch_context_recv_message_length = PInvokeMethods.grpcsharp_batch_context_recv_message_length;
+ this.grpcsharp_batch_context_recv_message_to_buffer = PInvokeMethods.grpcsharp_batch_context_recv_message_to_buffer;
+ this.grpcsharp_batch_context_recv_status_on_client_status = PInvokeMethods.grpcsharp_batch_context_recv_status_on_client_status;
+ this.grpcsharp_batch_context_recv_status_on_client_details = PInvokeMethods.grpcsharp_batch_context_recv_status_on_client_details;
+ this.grpcsharp_batch_context_recv_status_on_client_trailing_metadata = PInvokeMethods.grpcsharp_batch_context_recv_status_on_client_trailing_metadata;
+ this.grpcsharp_batch_context_server_rpc_new_call = PInvokeMethods.grpcsharp_batch_context_server_rpc_new_call;
+ this.grpcsharp_batch_context_server_rpc_new_method = PInvokeMethods.grpcsharp_batch_context_server_rpc_new_method;
+ this.grpcsharp_batch_context_server_rpc_new_host = PInvokeMethods.grpcsharp_batch_context_server_rpc_new_host;
+ this.grpcsharp_batch_context_server_rpc_new_deadline = PInvokeMethods.grpcsharp_batch_context_server_rpc_new_deadline;
+ this.grpcsharp_batch_context_server_rpc_new_request_metadata = PInvokeMethods.grpcsharp_batch_context_server_rpc_new_request_metadata;
+ this.grpcsharp_batch_context_recv_close_on_server_cancelled = PInvokeMethods.grpcsharp_batch_context_recv_close_on_server_cancelled;
+ this.grpcsharp_batch_context_destroy = PInvokeMethods.grpcsharp_batch_context_destroy;
+
+ this.grpcsharp_composite_call_credentials_create = PInvokeMethods.grpcsharp_composite_call_credentials_create;
+ this.grpcsharp_call_credentials_release = PInvokeMethods.grpcsharp_call_credentials_release;
+
+ this.grpcsharp_call_cancel = PInvokeMethods.grpcsharp_call_cancel;
+ this.grpcsharp_call_cancel_with_status = PInvokeMethods.grpcsharp_call_cancel_with_status;
+ this.grpcsharp_call_start_unary = PInvokeMethods.grpcsharp_call_start_unary;
+ this.grpcsharp_call_start_client_streaming = PInvokeMethods.grpcsharp_call_start_client_streaming;
+ this.grpcsharp_call_start_server_streaming = PInvokeMethods.grpcsharp_call_start_server_streaming;
+ this.grpcsharp_call_start_duplex_streaming = PInvokeMethods.grpcsharp_call_start_duplex_streaming;
+ this.grpcsharp_call_send_message = PInvokeMethods.grpcsharp_call_send_message;
+ this.grpcsharp_call_send_close_from_client = PInvokeMethods.grpcsharp_call_send_close_from_client;
+ this.grpcsharp_call_send_status_from_server = PInvokeMethods.grpcsharp_call_send_status_from_server;
+ this.grpcsharp_call_recv_message = PInvokeMethods.grpcsharp_call_recv_message;
+ this.grpcsharp_call_recv_initial_metadata = PInvokeMethods.grpcsharp_call_recv_initial_metadata;
+ this.grpcsharp_call_start_serverside = PInvokeMethods.grpcsharp_call_start_serverside;
+ this.grpcsharp_call_send_initial_metadata = PInvokeMethods.grpcsharp_call_send_initial_metadata;
+ this.grpcsharp_call_set_credentials = PInvokeMethods.grpcsharp_call_set_credentials;
+ this.grpcsharp_call_get_peer = PInvokeMethods.grpcsharp_call_get_peer;
+ this.grpcsharp_call_destroy = PInvokeMethods.grpcsharp_call_destroy;
+
+ this.grpcsharp_channel_args_create = PInvokeMethods.grpcsharp_channel_args_create;
+ this.grpcsharp_channel_args_set_string = PInvokeMethods.grpcsharp_channel_args_set_string;
+ this.grpcsharp_channel_args_set_integer = PInvokeMethods.grpcsharp_channel_args_set_integer;
+ this.grpcsharp_channel_args_destroy = PInvokeMethods.grpcsharp_channel_args_destroy;
+
+ this.grpcsharp_ssl_credentials_create = PInvokeMethods.grpcsharp_ssl_credentials_create;
+ this.grpcsharp_composite_channel_credentials_create = PInvokeMethods.grpcsharp_composite_channel_credentials_create;
+ this.grpcsharp_channel_credentials_release = PInvokeMethods.grpcsharp_channel_credentials_release;
+
+ this.grpcsharp_insecure_channel_create = PInvokeMethods.grpcsharp_insecure_channel_create;
+ this.grpcsharp_secure_channel_create = PInvokeMethods.grpcsharp_secure_channel_create;
+ this.grpcsharp_channel_create_call = PInvokeMethods.grpcsharp_channel_create_call;
+ this.grpcsharp_channel_check_connectivity_state = PInvokeMethods.grpcsharp_channel_check_connectivity_state;
+ this.grpcsharp_channel_watch_connectivity_state = PInvokeMethods.grpcsharp_channel_watch_connectivity_state;
+ this.grpcsharp_channel_get_target = PInvokeMethods.grpcsharp_channel_get_target;
+ this.grpcsharp_channel_destroy = PInvokeMethods.grpcsharp_channel_destroy;
+
+ this.grpcsharp_sizeof_grpc_event = PInvokeMethods.grpcsharp_sizeof_grpc_event;
+
+ this.grpcsharp_completion_queue_create = PInvokeMethods.grpcsharp_completion_queue_create;
+ this.grpcsharp_completion_queue_shutdown = PInvokeMethods.grpcsharp_completion_queue_shutdown;
+ this.grpcsharp_completion_queue_next = PInvokeMethods.grpcsharp_completion_queue_next;
+ this.grpcsharp_completion_queue_pluck = PInvokeMethods.grpcsharp_completion_queue_pluck;
+ this.grpcsharp_completion_queue_destroy = PInvokeMethods.grpcsharp_completion_queue_destroy;
+
+ this.gprsharp_free = PInvokeMethods.gprsharp_free;
+
+ this.grpcsharp_metadata_array_create = PInvokeMethods.grpcsharp_metadata_array_create;
+ this.grpcsharp_metadata_array_add = PInvokeMethods.grpcsharp_metadata_array_add;
+ this.grpcsharp_metadata_array_count = PInvokeMethods.grpcsharp_metadata_array_count;
+ this.grpcsharp_metadata_array_get_key = PInvokeMethods.grpcsharp_metadata_array_get_key;
+ this.grpcsharp_metadata_array_get_value = PInvokeMethods.grpcsharp_metadata_array_get_value;
+ this.grpcsharp_metadata_array_get_value_length = PInvokeMethods.grpcsharp_metadata_array_get_value_length;
+ this.grpcsharp_metadata_array_destroy_full = PInvokeMethods.grpcsharp_metadata_array_destroy_full;
+
+ this.grpcsharp_redirect_log = PInvokeMethods.grpcsharp_redirect_log;
+
+ this.grpcsharp_metadata_credentials_create_from_plugin = PInvokeMethods.grpcsharp_metadata_credentials_create_from_plugin;
+ this.grpcsharp_metadata_credentials_notify_from_plugin = PInvokeMethods.grpcsharp_metadata_credentials_notify_from_plugin;
+
+ this.grpcsharp_ssl_server_credentials_create = PInvokeMethods.grpcsharp_ssl_server_credentials_create;
+ this.grpcsharp_server_credentials_release = PInvokeMethods.grpcsharp_server_credentials_release;
+
+ this.grpcsharp_server_create = PInvokeMethods.grpcsharp_server_create;
+ this.grpcsharp_server_add_insecure_http2_port = PInvokeMethods.grpcsharp_server_add_insecure_http2_port;
+ this.grpcsharp_server_add_secure_http2_port = PInvokeMethods.grpcsharp_server_add_secure_http2_port;
+ this.grpcsharp_server_start = PInvokeMethods.grpcsharp_server_start;
+ this.grpcsharp_server_request_call = PInvokeMethods.grpcsharp_server_request_call;
+ this.grpcsharp_server_cancel_all_calls = PInvokeMethods.grpcsharp_server_cancel_all_calls;
+ this.grpcsharp_server_shutdown_and_notify_callback = PInvokeMethods.grpcsharp_server_shutdown_and_notify_callback;
+ this.grpcsharp_server_destroy = PInvokeMethods.grpcsharp_server_destroy;
+
+ this.gprsharp_now = PInvokeMethods.gprsharp_now;
+ this.gprsharp_inf_future = PInvokeMethods.gprsharp_inf_future;
+ this.gprsharp_inf_past = PInvokeMethods.gprsharp_inf_past;
+ this.gprsharp_convert_clock_type = PInvokeMethods.gprsharp_convert_clock_type;
+ this.gprsharp_sizeof_timespec = PInvokeMethods.gprsharp_sizeof_timespec;
+
+ this.grpcsharp_test_callback = PInvokeMethods.grpcsharp_test_callback;
+ this.grpcsharp_test_nop = PInvokeMethods.grpcsharp_test_nop;
+ }
+ }
+
+ /// <summary>
+ /// Gets singleton instance of this class.
+ /// </summary>
+ public static NativeMethods Get()
+ {
+ return NativeExtension.Get().NativeMethods;
+ }
+
+ static T GetMethodDelegate<T>(UnmanagedLibrary library)
+ where T : class
+ {
+ var methodName = RemoveStringSuffix(typeof(T).Name, "_delegate");
+ return library.GetNativeMethodDelegate<T>(methodName);
+ }
+
+ static string RemoveStringSuffix(string str, string toRemove)
+ {
+ if (!str.EndsWith(toRemove))
+ {
+ return str;
+ }
+ return str.Substring(0, str.Length - toRemove.Length);
+ }
+
+ /// <summary>
+ /// Delegate types for all published native methods. Declared under inner class to prevent scope pollution.
+ /// </summary>
+ public class Delegates
+ {
+ public delegate void grpcsharp_init_delegate();
+ public delegate void grpcsharp_shutdown_delegate();
+ public delegate IntPtr grpcsharp_version_string_delegate(); // returns not-owned const char*
+
+ public delegate BatchContextSafeHandle grpcsharp_batch_context_create_delegate();
+ public delegate IntPtr grpcsharp_batch_context_recv_initial_metadata_delegate(BatchContextSafeHandle ctx);
+ public delegate IntPtr grpcsharp_batch_context_recv_message_length_delegate(BatchContextSafeHandle ctx);
+ public delegate void grpcsharp_batch_context_recv_message_to_buffer_delegate(BatchContextSafeHandle ctx, byte[] buffer, UIntPtr bufferLen);
+ public delegate StatusCode grpcsharp_batch_context_recv_status_on_client_status_delegate(BatchContextSafeHandle ctx);
+ public delegate IntPtr grpcsharp_batch_context_recv_status_on_client_details_delegate(BatchContextSafeHandle ctx); // returns const char*
+ public delegate IntPtr grpcsharp_batch_context_recv_status_on_client_trailing_metadata_delegate(BatchContextSafeHandle ctx);
+ public delegate CallSafeHandle grpcsharp_batch_context_server_rpc_new_call_delegate(BatchContextSafeHandle ctx);
+ public delegate IntPtr grpcsharp_batch_context_server_rpc_new_method_delegate(BatchContextSafeHandle ctx); // returns const char*
+ public delegate IntPtr grpcsharp_batch_context_server_rpc_new_host_delegate(BatchContextSafeHandle ctx); // returns const char*
+ public delegate Timespec grpcsharp_batch_context_server_rpc_new_deadline_delegate(BatchContextSafeHandle ctx);
+ public delegate IntPtr grpcsharp_batch_context_server_rpc_new_request_metadata_delegate(BatchContextSafeHandle ctx);
+ public delegate int grpcsharp_batch_context_recv_close_on_server_cancelled_delegate(BatchContextSafeHandle ctx);
+ public delegate void grpcsharp_batch_context_destroy_delegate(IntPtr ctx);
+
+ public delegate CallCredentialsSafeHandle grpcsharp_composite_call_credentials_create_delegate(CallCredentialsSafeHandle creds1, CallCredentialsSafeHandle creds2);
+ public delegate void grpcsharp_call_credentials_release_delegate(IntPtr credentials);
+
+ public delegate GRPCCallError grpcsharp_call_cancel_delegate(CallSafeHandle call);
+ public delegate GRPCCallError grpcsharp_call_cancel_with_status_delegate(CallSafeHandle call, StatusCode status, string description);
+ public delegate GRPCCallError grpcsharp_call_start_unary_delegate(CallSafeHandle call,
+ BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags);
+ public delegate GRPCCallError grpcsharp_call_start_client_streaming_delegate(CallSafeHandle call,
+ BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
+ public delegate GRPCCallError grpcsharp_call_start_server_streaming_delegate(CallSafeHandle call,
+ BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len,
+ MetadataArraySafeHandle metadataArray, WriteFlags writeFlags);
+ public delegate GRPCCallError grpcsharp_call_start_duplex_streaming_delegate(CallSafeHandle call,
+ BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
+ public delegate GRPCCallError grpcsharp_call_send_message_delegate(CallSafeHandle call,
+ BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len, WriteFlags writeFlags, bool sendEmptyInitialMetadata);
+ public delegate GRPCCallError grpcsharp_call_send_close_from_client_delegate(CallSafeHandle call,
+ BatchContextSafeHandle ctx);
+ public delegate GRPCCallError grpcsharp_call_send_status_from_server_delegate(CallSafeHandle call,
+ BatchContextSafeHandle ctx, StatusCode statusCode, string statusMessage, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata);
+ public delegate GRPCCallError grpcsharp_call_recv_message_delegate(CallSafeHandle call,
+ BatchContextSafeHandle ctx);
+ public delegate GRPCCallError grpcsharp_call_recv_initial_metadata_delegate(CallSafeHandle call,
+ BatchContextSafeHandle ctx);
+ public delegate GRPCCallError grpcsharp_call_start_serverside_delegate(CallSafeHandle call,
+ BatchContextSafeHandle ctx);
+ public delegate GRPCCallError grpcsharp_call_send_initial_metadata_delegate(CallSafeHandle call,
+ BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
+ public delegate GRPCCallError grpcsharp_call_set_credentials_delegate(CallSafeHandle call, CallCredentialsSafeHandle credentials);
+ public delegate CStringSafeHandle grpcsharp_call_get_peer_delegate(CallSafeHandle call);
+ public delegate void grpcsharp_call_destroy_delegate(IntPtr call);
+
+ public delegate ChannelArgsSafeHandle grpcsharp_channel_args_create_delegate(UIntPtr numArgs);
+ public delegate void grpcsharp_channel_args_set_string_delegate(ChannelArgsSafeHandle args, UIntPtr index, string key, string value);
+ public delegate void grpcsharp_channel_args_set_integer_delegate(ChannelArgsSafeHandle args, UIntPtr index, string key, int value);
+ public delegate void grpcsharp_channel_args_destroy_delegate(IntPtr args);
+
+ public delegate ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create_delegate(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey);
+ public delegate ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create_delegate(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds);
+ public delegate void grpcsharp_channel_credentials_release_delegate(IntPtr credentials);
+
+ public delegate ChannelSafeHandle grpcsharp_insecure_channel_create_delegate(string target, ChannelArgsSafeHandle channelArgs);
+ public delegate ChannelSafeHandle grpcsharp_secure_channel_create_delegate(ChannelCredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs);
+ public delegate CallSafeHandle grpcsharp_channel_create_call_delegate(ChannelSafeHandle channel, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline);
+ public delegate ChannelState grpcsharp_channel_check_connectivity_state_delegate(ChannelSafeHandle channel, int tryToConnect);
+ public delegate void grpcsharp_channel_watch_connectivity_state_delegate(ChannelSafeHandle channel, ChannelState lastObservedState,
+ Timespec deadline, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
+ public delegate CStringSafeHandle grpcsharp_channel_get_target_delegate(ChannelSafeHandle call);
+ public delegate void grpcsharp_channel_destroy_delegate(IntPtr channel);
+
+ public delegate int grpcsharp_sizeof_grpc_event_delegate();
+
+ public delegate CompletionQueueSafeHandle grpcsharp_completion_queue_create_delegate();
+ public delegate void grpcsharp_completion_queue_shutdown_delegate(CompletionQueueSafeHandle cq);
+ public delegate CompletionQueueEvent grpcsharp_completion_queue_next_delegate(CompletionQueueSafeHandle cq);
+ public delegate CompletionQueueEvent grpcsharp_completion_queue_pluck_delegate(CompletionQueueSafeHandle cq, IntPtr tag);
+ public delegate void grpcsharp_completion_queue_destroy_delegate(IntPtr cq);
+
+ public delegate void gprsharp_free_delegate(IntPtr ptr);
+
+ public delegate MetadataArraySafeHandle grpcsharp_metadata_array_create_delegate(UIntPtr capacity);
+ public delegate void grpcsharp_metadata_array_add_delegate(MetadataArraySafeHandle array, string key, byte[] value, UIntPtr valueLength);
+ public delegate UIntPtr grpcsharp_metadata_array_count_delegate(IntPtr metadataArray);
+ public delegate IntPtr grpcsharp_metadata_array_get_key_delegate(IntPtr metadataArray, UIntPtr index);
+ public delegate IntPtr grpcsharp_metadata_array_get_value_delegate(IntPtr metadataArray, UIntPtr index);
+ public delegate UIntPtr grpcsharp_metadata_array_get_value_length_delegate(IntPtr metadataArray, UIntPtr index);
+ public delegate void grpcsharp_metadata_array_destroy_full_delegate(IntPtr array);
+
+ public delegate void grpcsharp_redirect_log_delegate(GprLogDelegate callback);
+
+ public delegate CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin_delegate(NativeMetadataInterceptor interceptor);
+ public delegate void grpcsharp_metadata_credentials_notify_from_plugin_delegate(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails);
+
+ public delegate ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create_delegate(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, bool forceClientAuth);
+ public delegate void grpcsharp_server_credentials_release_delegate(IntPtr credentials);
+
+ public delegate ServerSafeHandle grpcsharp_server_create_delegate(CompletionQueueSafeHandle cq, ChannelArgsSafeHandle args);
+ public delegate int grpcsharp_server_add_insecure_http2_port_delegate(ServerSafeHandle server, string addr);
+ public delegate int grpcsharp_server_add_secure_http2_port_delegate(ServerSafeHandle server, string addr, ServerCredentialsSafeHandle creds);
+ public delegate void grpcsharp_server_start_delegate(ServerSafeHandle server);
+ public delegate GRPCCallError grpcsharp_server_request_call_delegate(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
+ public delegate void grpcsharp_server_cancel_all_calls_delegate(ServerSafeHandle server);
+ public delegate void grpcsharp_server_shutdown_and_notify_callback_delegate(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
+ public delegate void grpcsharp_server_destroy_delegate(IntPtr server);
+
+ public delegate Timespec gprsharp_now_delegate(GPRClockType clockType);
+ public delegate Timespec gprsharp_inf_future_delegate(GPRClockType clockType);
+ public delegate Timespec gprsharp_inf_past_delegate(GPRClockType clockType);
+
+ public delegate Timespec gprsharp_convert_clock_type_delegate(Timespec t, GPRClockType targetClock);
+ public delegate int gprsharp_sizeof_timespec_delegate();
+
+ public delegate GRPCCallError grpcsharp_test_callback_delegate([MarshalAs(UnmanagedType.FunctionPtr)] OpCompletionDelegate callback);
+ public delegate IntPtr grpcsharp_test_nop_delegate(IntPtr ptr);
+ }
+
+ /// <summary>
+ /// Default PInvoke bindings for native methods that are used on Windows.
+ /// Alternatively, they can also be used as a fallback on Mono
+ /// (if libgrpc_csharp_ext is installed on your system, or is made accessible through e.g. LD_LIBRARY_PATH environment variable
+ /// or using Mono's dllMap feature).
+ /// </summary>
+ private class PInvokeMethods
+ {
+ // Environment
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern void grpcsharp_init();
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern void grpcsharp_shutdown();
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern IntPtr grpcsharp_version_string(); // returns not-owned const char*
+
+ // BatchContextSafeHandle
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern BatchContextSafeHandle grpcsharp_batch_context_create();
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern IntPtr grpcsharp_batch_context_recv_initial_metadata(BatchContextSafeHandle ctx);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern IntPtr grpcsharp_batch_context_recv_message_length(BatchContextSafeHandle ctx);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern void grpcsharp_batch_context_recv_message_to_buffer(BatchContextSafeHandle ctx, byte[] buffer, UIntPtr bufferLen);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern StatusCode grpcsharp_batch_context_recv_status_on_client_status(BatchContextSafeHandle ctx);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern IntPtr grpcsharp_batch_context_recv_status_on_client_details(BatchContextSafeHandle ctx); // returns const char*
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern IntPtr grpcsharp_batch_context_recv_status_on_client_trailing_metadata(BatchContextSafeHandle ctx);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern CallSafeHandle grpcsharp_batch_context_server_rpc_new_call(BatchContextSafeHandle ctx);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern IntPtr grpcsharp_batch_context_server_rpc_new_method(BatchContextSafeHandle ctx); // returns const char*
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern IntPtr grpcsharp_batch_context_server_rpc_new_host(BatchContextSafeHandle ctx); // returns const char*
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern Timespec grpcsharp_batch_context_server_rpc_new_deadline(BatchContextSafeHandle ctx);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern IntPtr grpcsharp_batch_context_server_rpc_new_request_metadata(BatchContextSafeHandle ctx);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern int grpcsharp_batch_context_recv_close_on_server_cancelled(BatchContextSafeHandle ctx);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern void grpcsharp_batch_context_destroy(IntPtr ctx);
+
+ // CallCredentialsSafeHandle
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern CallCredentialsSafeHandle grpcsharp_composite_call_credentials_create(CallCredentialsSafeHandle creds1, CallCredentialsSafeHandle creds2);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern void grpcsharp_call_credentials_release(IntPtr credentials);
+
+ // CallSafeHandle
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern GRPCCallError grpcsharp_call_cancel(CallSafeHandle call);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern GRPCCallError grpcsharp_call_cancel_with_status(CallSafeHandle call, StatusCode status, string description);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern GRPCCallError grpcsharp_call_start_unary(CallSafeHandle call,
+ BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len, MetadataArraySafeHandle metadataArray, WriteFlags writeFlags);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern GRPCCallError grpcsharp_call_start_client_streaming(CallSafeHandle call,
+ BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern GRPCCallError grpcsharp_call_start_server_streaming(CallSafeHandle call,
+ BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len,
+ MetadataArraySafeHandle metadataArray, WriteFlags writeFlags);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern GRPCCallError grpcsharp_call_start_duplex_streaming(CallSafeHandle call,
+ BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern GRPCCallError grpcsharp_call_send_message(CallSafeHandle call,
+ BatchContextSafeHandle ctx, byte[] send_buffer, UIntPtr send_buffer_len, WriteFlags writeFlags, bool sendEmptyInitialMetadata);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern GRPCCallError grpcsharp_call_send_close_from_client(CallSafeHandle call,
+ BatchContextSafeHandle ctx);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern GRPCCallError grpcsharp_call_send_status_from_server(CallSafeHandle call,
+ BatchContextSafeHandle ctx, StatusCode statusCode, string statusMessage, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern GRPCCallError grpcsharp_call_recv_message(CallSafeHandle call,
+ BatchContextSafeHandle ctx);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern GRPCCallError grpcsharp_call_recv_initial_metadata(CallSafeHandle call,
+ BatchContextSafeHandle ctx);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern GRPCCallError grpcsharp_call_start_serverside(CallSafeHandle call,
+ BatchContextSafeHandle ctx);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern GRPCCallError grpcsharp_call_send_initial_metadata(CallSafeHandle call,
+ BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern GRPCCallError grpcsharp_call_set_credentials(CallSafeHandle call, CallCredentialsSafeHandle credentials);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern CStringSafeHandle grpcsharp_call_get_peer(CallSafeHandle call);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern void grpcsharp_call_destroy(IntPtr call);
+
+ // ChannelArgsSafeHandle
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern ChannelArgsSafeHandle grpcsharp_channel_args_create(UIntPtr numArgs);
+
+ [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
+ public static extern void grpcsharp_channel_args_set_string(ChannelArgsSafeHandle args, UIntPtr index, string key, string value);
+
+ [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
+ public static extern void grpcsharp_channel_args_set_integer(ChannelArgsSafeHandle args, UIntPtr index, string key, int value);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern void grpcsharp_channel_args_destroy(IntPtr args);
+
+ // ChannelCredentialsSafeHandle
+
+ [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
+ public static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern void grpcsharp_channel_credentials_release(IntPtr credentials);
+
+ // ChannelSafeHandle
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern ChannelSafeHandle grpcsharp_insecure_channel_create(string target, ChannelArgsSafeHandle channelArgs);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern ChannelSafeHandle grpcsharp_secure_channel_create(ChannelCredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern CallSafeHandle grpcsharp_channel_create_call(ChannelSafeHandle channel, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern ChannelState grpcsharp_channel_check_connectivity_state(ChannelSafeHandle channel, int tryToConnect);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern void grpcsharp_channel_watch_connectivity_state(ChannelSafeHandle channel, ChannelState lastObservedState,
+ Timespec deadline, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern CStringSafeHandle grpcsharp_channel_get_target(ChannelSafeHandle call);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern void grpcsharp_channel_destroy(IntPtr channel);
+
+ // CompletionQueueEvent
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern int grpcsharp_sizeof_grpc_event();
+
+ // CompletionQueueSafeHandle
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern CompletionQueueSafeHandle grpcsharp_completion_queue_create();
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern void grpcsharp_completion_queue_shutdown(CompletionQueueSafeHandle cq);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern CompletionQueueEvent grpcsharp_completion_queue_next(CompletionQueueSafeHandle cq);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern CompletionQueueEvent grpcsharp_completion_queue_pluck(CompletionQueueSafeHandle cq, IntPtr tag);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern void grpcsharp_completion_queue_destroy(IntPtr cq);
+
+ // CStringSafeHandle
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern void gprsharp_free(IntPtr ptr);
+
+ // MetadataArraySafeHandle
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern MetadataArraySafeHandle grpcsharp_metadata_array_create(UIntPtr capacity);
+
+ [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
+ public static extern void grpcsharp_metadata_array_add(MetadataArraySafeHandle array, string key, byte[] value, UIntPtr valueLength);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern UIntPtr grpcsharp_metadata_array_count(IntPtr metadataArray);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern IntPtr grpcsharp_metadata_array_get_key(IntPtr metadataArray, UIntPtr index);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern IntPtr grpcsharp_metadata_array_get_value(IntPtr metadataArray, UIntPtr index);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern UIntPtr grpcsharp_metadata_array_get_value_length(IntPtr metadataArray, UIntPtr index);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern void grpcsharp_metadata_array_destroy_full(IntPtr array);
+
+ // NativeLogRedirector
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern void grpcsharp_redirect_log(GprLogDelegate callback);
+
+ // NativeMetadataCredentialsPlugin
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(NativeMetadataInterceptor interceptor);
+
+ [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
+ public static extern void grpcsharp_metadata_credentials_notify_from_plugin(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails);
+
+ // ServerCredentialsSafeHandle
+
+ [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
+ public static extern ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, bool forceClientAuth);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern void grpcsharp_server_credentials_release(IntPtr credentials);
+
+ // ServerSafeHandle
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern ServerSafeHandle grpcsharp_server_create(CompletionQueueSafeHandle cq, ChannelArgsSafeHandle args);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern int grpcsharp_server_add_insecure_http2_port(ServerSafeHandle server, string addr);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern int grpcsharp_server_add_secure_http2_port(ServerSafeHandle server, string addr, ServerCredentialsSafeHandle creds);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern void grpcsharp_server_start(ServerSafeHandle server);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern GRPCCallError grpcsharp_server_request_call(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern void grpcsharp_server_cancel_all_calls(ServerSafeHandle server);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern void grpcsharp_server_shutdown_and_notify_callback(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern void grpcsharp_server_destroy(IntPtr server);
+
+ // Timespec
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern Timespec gprsharp_now(GPRClockType clockType);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern Timespec gprsharp_inf_future(GPRClockType clockType);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern Timespec gprsharp_inf_past(GPRClockType clockType);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern Timespec gprsharp_convert_clock_type(Timespec t, GPRClockType targetClock);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern int gprsharp_sizeof_timespec();
+
+ // Testing
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern GRPCCallError grpcsharp_test_callback([MarshalAs(UnmanagedType.FunctionPtr)] OpCompletionDelegate callback);
+
+ [DllImport("grpc_csharp_ext.dll")]
+ public static extern IntPtr grpcsharp_test_nop(IntPtr ptr);
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Internal/PlatformApis.cs b/src/csharp/Grpc.Core/Internal/PlatformApis.cs
new file mode 100644
index 0000000000..e6c5765b61
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/PlatformApis.cs
@@ -0,0 +1,110 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Concurrent;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+namespace Grpc.Core.Internal
+{
+ /// <summary>
+ /// Utility methods for detecting platform and architecture.
+ /// </summary>
+ internal static class PlatformApis
+ {
+ static readonly bool isLinux;
+ static readonly bool isMacOSX;
+ static readonly bool isWindows;
+
+ static PlatformApis()
+ {
+ var platform = Environment.OSVersion.Platform;
+
+ // PlatformID.MacOSX is never returned, commonly used trick is to identify Mac is by using uname.
+ isMacOSX = (platform == PlatformID.Unix && GetUname() == "Darwin");
+ isLinux = (platform == PlatformID.Unix && !isMacOSX);
+ isWindows = (platform == PlatformID.Win32NT || platform == PlatformID.Win32S || platform == PlatformID.Win32Windows);
+ }
+
+ public static bool IsLinux
+ {
+ get { return isLinux; }
+ }
+
+ public static bool IsMacOSX
+ {
+ get { return isMacOSX; }
+ }
+
+ public static bool IsWindows
+ {
+ get { return isWindows; }
+ }
+
+ public static bool Is64Bit
+ {
+ get { return IntPtr.Size == 8; }
+ }
+
+ [DllImport("libc")]
+ static extern int uname(IntPtr buf);
+
+ static string GetUname()
+ {
+ var buffer = Marshal.AllocHGlobal(8192);
+ try
+ {
+ if (uname(buffer) == 0)
+ {
+ return Marshal.PtrToStringAnsi(buffer);
+ }
+ return string.Empty;
+ }
+ catch
+ {
+ return string.Empty;
+ }
+ finally
+ {
+ if (buffer != IntPtr.Zero)
+ {
+ Marshal.FreeHGlobal(buffer);
+ }
+ }
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs
index 51e352a18b..d50e1c7269 100644
--- a/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs
@@ -41,11 +41,7 @@ namespace Grpc.Core.Internal
/// </summary>
internal class ServerCredentialsSafeHandle : SafeHandleZeroIsInvalid
{
- [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
- static extern ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, bool forceClientAuth);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern void grpcsharp_server_credentials_release(IntPtr credentials);
+ static readonly NativeMethods Native = NativeMethods.Get();
private ServerCredentialsSafeHandle()
{
@@ -54,15 +50,15 @@ namespace Grpc.Core.Internal
public static ServerCredentialsSafeHandle CreateSslCredentials(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, bool forceClientAuth)
{
Preconditions.CheckArgument(keyCertPairCertChainArray.Length == keyCertPairPrivateKeyArray.Length);
- return grpcsharp_ssl_server_credentials_create(pemRootCerts,
- keyCertPairCertChainArray, keyCertPairPrivateKeyArray,
- new UIntPtr((ulong)keyCertPairCertChainArray.Length),
- forceClientAuth);
+ return Native.grpcsharp_ssl_server_credentials_create(pemRootCerts,
+ keyCertPairCertChainArray, keyCertPairPrivateKeyArray,
+ new UIntPtr((ulong)keyCertPairCertChainArray.Length),
+ forceClientAuth);
}
protected override bool ReleaseHandle()
{
- grpcsharp_server_credentials_release(handle);
+ Native.grpcsharp_server_credentials_release(handle);
return true;
}
}
diff --git a/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
index 5ee7ac14e8..6b5f70e220 100644
--- a/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
@@ -44,29 +44,7 @@ namespace Grpc.Core.Internal
/// </summary>
internal sealed class ServerSafeHandle : SafeHandleZeroIsInvalid
{
- [DllImport("grpc_csharp_ext.dll")]
- static extern ServerSafeHandle grpcsharp_server_create(CompletionQueueSafeHandle cq, ChannelArgsSafeHandle args);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern int grpcsharp_server_add_insecure_http2_port(ServerSafeHandle server, string addr);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern int grpcsharp_server_add_secure_http2_port(ServerSafeHandle server, string addr, ServerCredentialsSafeHandle creds);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern void grpcsharp_server_start(ServerSafeHandle server);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern GRPCCallError grpcsharp_server_request_call(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern void grpcsharp_server_cancel_all_calls(ServerSafeHandle server);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern void grpcsharp_server_shutdown_and_notify_callback(ServerSafeHandle server, CompletionQueueSafeHandle cq, BatchContextSafeHandle ctx);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern void grpcsharp_server_destroy(IntPtr server);
+ static readonly NativeMethods Native = NativeMethods.Get();
private ServerSafeHandle()
{
@@ -77,41 +55,41 @@ namespace Grpc.Core.Internal
// Increment reference count for the native gRPC environment to make sure we don't do grpc_shutdown() before destroying the server handle.
// Doing so would make object finalizer crash if we end up abandoning the handle.
GrpcEnvironment.GrpcNativeInit();
- return grpcsharp_server_create(cq, args);
+ return Native.grpcsharp_server_create(cq, args);
}
public int AddInsecurePort(string addr)
{
- return grpcsharp_server_add_insecure_http2_port(this, addr);
+ return Native.grpcsharp_server_add_insecure_http2_port(this, addr);
}
public int AddSecurePort(string addr, ServerCredentialsSafeHandle credentials)
{
- return grpcsharp_server_add_secure_http2_port(this, addr, credentials);
+ return Native.grpcsharp_server_add_secure_http2_port(this, addr, credentials);
}
public void Start()
{
- grpcsharp_server_start(this);
+ Native.grpcsharp_server_start(this);
}
public void ShutdownAndNotify(BatchCompletionDelegate callback, GrpcEnvironment environment)
{
var ctx = BatchContextSafeHandle.Create();
environment.CompletionRegistry.RegisterBatchCompletion(ctx, callback);
- grpcsharp_server_shutdown_and_notify_callback(this, environment.CompletionQueue, ctx);
+ Native.grpcsharp_server_shutdown_and_notify_callback(this, environment.CompletionQueue, ctx);
}
public void RequestCall(BatchCompletionDelegate callback, GrpcEnvironment environment)
{
var ctx = BatchContextSafeHandle.Create();
environment.CompletionRegistry.RegisterBatchCompletion(ctx, callback);
- grpcsharp_server_request_call(this, environment.CompletionQueue, ctx).CheckOk();
+ Native.grpcsharp_server_request_call(this, environment.CompletionQueue, ctx).CheckOk();
}
protected override bool ReleaseHandle()
{
- grpcsharp_server_destroy(handle);
+ Native.grpcsharp_server_destroy(handle);
GrpcEnvironment.GrpcNativeShutdown();
return true;
}
@@ -119,7 +97,7 @@ namespace Grpc.Core.Internal
// Only to be called after ShutdownAndNotify.
public void CancelAllCalls()
{
- grpcsharp_server_cancel_all_calls(this);
+ Native.grpcsharp_server_cancel_all_calls(this);
}
}
}
diff --git a/src/csharp/Grpc.Core/Internal/Timespec.cs b/src/csharp/Grpc.Core/Internal/Timespec.cs
index 3031175c8a..18bcd8c76d 100644
--- a/src/csharp/Grpc.Core/Internal/Timespec.cs
+++ b/src/csharp/Grpc.Core/Internal/Timespec.cs
@@ -46,23 +46,9 @@ namespace Grpc.Core.Internal
const long NanosPerTick = 100;
const long TicksPerSecond = NanosPerSecond / NanosPerTick;
+ static readonly NativeMethods Native = NativeMethods.Get();
static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);
- [DllImport("grpc_csharp_ext.dll")]
- static extern Timespec gprsharp_now(GPRClockType clockType);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern Timespec gprsharp_inf_future(GPRClockType clockType);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern Timespec gprsharp_inf_past(GPRClockType clockType);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern Timespec gprsharp_convert_clock_type(Timespec t, GPRClockType targetClock);
-
- [DllImport("grpc_csharp_ext.dll")]
- static extern int gprsharp_sizeof_timespec();
-
public Timespec(long tv_sec, int tv_nsec) : this(tv_sec, tv_nsec, GPRClockType.Realtime)
{
}
@@ -85,7 +71,7 @@ namespace Grpc.Core.Internal
{
get
{
- return gprsharp_inf_future(GPRClockType.Realtime);
+ return Native.gprsharp_inf_future(GPRClockType.Realtime);
}
}
@@ -96,7 +82,7 @@ namespace Grpc.Core.Internal
{
get
{
- return gprsharp_inf_past(GPRClockType.Realtime);
+ return Native.gprsharp_inf_past(GPRClockType.Realtime);
}
}
@@ -107,7 +93,7 @@ namespace Grpc.Core.Internal
{
get
{
- return gprsharp_now(GPRClockType.Realtime);
+ return Native.gprsharp_now(GPRClockType.Realtime);
}
}
@@ -138,7 +124,7 @@ namespace Grpc.Core.Internal
/// </summary>
public Timespec ToClockType(GPRClockType targetClock)
{
- return gprsharp_convert_clock_type(this, targetClock);
+ return Native.gprsharp_convert_clock_type(this, targetClock);
}
/// <summary>
@@ -241,7 +227,7 @@ namespace Grpc.Core.Internal
{
get
{
- return gprsharp_now(GPRClockType.Precise);
+ return Native.gprsharp_now(GPRClockType.Precise);
}
}
@@ -249,7 +235,7 @@ namespace Grpc.Core.Internal
{
get
{
- return gprsharp_sizeof_timespec();
+ return Native.gprsharp_sizeof_timespec();
}
}
}
diff --git a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs
new file mode 100644
index 0000000000..9a8b8ab633
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs
@@ -0,0 +1,158 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Concurrent;
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+using Grpc.Core.Logging;
+using Grpc.Core.Utils;
+
+namespace Grpc.Core.Internal
+{
+ /// <summary>
+ /// Represents a dynamically loaded unmanaged library in a (partially) platform independent manner.
+ /// An important difference in library loading semantics is that on Windows, once we load a dynamic library using LoadLibrary,
+ /// that library becomes instantly available for <c>DllImport</c> P/Invoke calls referring to the same library name.
+ /// On Unix systems, dlopen has somewhat different semantics, so we need to use dlsym and <c>Marshal.GetDelegateForFunctionPointer</c>
+ /// to obtain delegates to native methods.
+ /// See http://stackoverflow.com/questions/13461989/p-invoke-to-dynamically-loaded-library-on-mono.
+ /// </summary>
+ internal class UnmanagedLibrary
+ {
+ static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<UnmanagedLibrary>();
+
+ // flags for dlopen
+ const int RTLD_LAZY = 1;
+ const int RTLD_GLOBAL = 8;
+
+ readonly string libraryPath;
+ readonly IntPtr handle;
+
+ public UnmanagedLibrary(string libraryPath)
+ {
+ this.libraryPath = Preconditions.CheckNotNull(libraryPath);
+
+ if (!File.Exists(this.libraryPath))
+ {
+ throw new FileNotFoundException("Error loading native library. File does not exist.", this.libraryPath);
+ }
+
+ Logger.Debug("Attempting to load native library \"{0}\"", this.libraryPath);
+
+ this.handle = PlatformSpecificLoadLibrary(this.libraryPath);
+
+ if (this.handle == IntPtr.Zero)
+ {
+ throw new IOException(string.Format("Error loading native library \"{0}\"", this.libraryPath));
+ }
+ }
+
+ /// <summary>
+ /// Loads symbol in a platform specific way.
+ /// </summary>
+ /// <param name="symbolName"></param>
+ /// <returns></returns>
+ public IntPtr LoadSymbol(string symbolName)
+ {
+ if (PlatformApis.IsLinux)
+ {
+ return Linux.dlsym(this.handle, symbolName);
+ }
+ if (PlatformApis.IsMacOSX)
+ {
+ return MacOSX.dlsym(this.handle, symbolName);
+ }
+ throw new InvalidOperationException("Unsupported platform.");
+ }
+
+ public T GetNativeMethodDelegate<T>(string methodName)
+ where T : class
+ {
+ var ptr = LoadSymbol(methodName);
+ if (ptr == IntPtr.Zero)
+ {
+ throw new MissingMethodException(string.Format("The native method \"{0}\" does not exist", methodName));
+ }
+ return Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T;
+ }
+
+ /// <summary>
+ /// Loads library in a platform specific way.
+ /// </summary>
+ private static IntPtr PlatformSpecificLoadLibrary(string libraryPath)
+ {
+ if (PlatformApis.IsWindows)
+ {
+ return Windows.LoadLibrary(libraryPath);
+ }
+ if (PlatformApis.IsLinux)
+ {
+ return Linux.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY);
+ }
+ if (PlatformApis.IsMacOSX)
+ {
+ return MacOSX.dlopen(libraryPath, RTLD_GLOBAL + RTLD_LAZY);
+ }
+ throw new InvalidOperationException("Unsupported platform.");
+ }
+
+ private static class Windows
+ {
+ [DllImport("kernel32.dll")]
+ internal static extern IntPtr LoadLibrary(string filename);
+ }
+
+ private static class Linux
+ {
+ [DllImport("libdl.so")]
+ internal static extern IntPtr dlopen(string filename, int flags);
+
+ [DllImport("libdl.so")]
+ internal static extern IntPtr dlsym(IntPtr handle, string symbol);
+ }
+
+ private static class MacOSX
+ {
+ [DllImport("libSystem.dylib")]
+ internal static extern IntPtr dlopen(string filename, int flags);
+
+ [DllImport("libSystem.dylib")]
+ internal static extern IntPtr dlsym(IntPtr handle, string symbol);
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/NativeDeps.Linux.targets b/src/csharp/Grpc.Core/NativeDeps.Linux.targets
new file mode 100644
index 0000000000..a3848c6f2e
--- /dev/null
+++ b/src/csharp/Grpc.Core/NativeDeps.Linux.targets
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Content Include="..\..\..\libs\$(NativeDependenciesConfigurationUnix)\libgrpc_csharp_ext.so">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ <Link>nativelibs\linux_x64\libgrpc_csharp_ext.so</Link>
+ </Content>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/src/csharp/Grpc.Core/NativeDeps.Mac.targets b/src/csharp/Grpc.Core/NativeDeps.Mac.targets
new file mode 100644
index 0000000000..c3c6264fd3
--- /dev/null
+++ b/src/csharp/Grpc.Core/NativeDeps.Mac.targets
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Content Include="..\..\..\libs\$(NativeDependenciesConfigurationUnix)\libgrpc_csharp_ext.dylib">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ <Link>nativelibs\macosx_x86\libgrpc_csharp_ext.dylib</Link>
+ </Content>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/src/csharp/Grpc.Core/NativeDeps.Windows.targets b/src/csharp/Grpc.Core/NativeDeps.Windows.targets
new file mode 100644
index 0000000000..f6a3405e29
--- /dev/null
+++ b/src/csharp/Grpc.Core/NativeDeps.Windows.targets
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Content Include="..\..\..\vsprojects\$(NativeDependenciesConfiguration)\grpc_csharp_ext.dll">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ <Link>nativelibs\windows_x86\grpc_csharp_ext.dll</Link>
+ </Content>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/src/csharp/Grpc.Core/NativeDeps.targets b/src/csharp/Grpc.Core/NativeDeps.targets
new file mode 100644
index 0000000000..66c5ec1292
--- /dev/null
+++ b/src/csharp/Grpc.Core/NativeDeps.targets
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+ <PropertyGroup Condition=" '$(NativeDependenciesConfiguration)' == '' ">
+ <NativeDependenciesConfiguration Condition=" '$(Configuration)' == 'Debug' ">Debug</NativeDependenciesConfiguration>
+ <NativeDependenciesConfiguration Condition=" '$(Configuration)' == 'Release' ">Release</NativeDependenciesConfiguration>
+ <NativeDependenciesConfiguration Condition=" '$(Configuration)' == 'ReleaseSigned' ">Release</NativeDependenciesConfiguration>
+ </PropertyGroup>
+
+ <PropertyGroup Condition=" '$(NativeDependenciesConfigurationUnix)' == '' ">
+ <NativeDependenciesConfigurationUnix Condition=" '$(Configuration)' == 'Debug' ">dbg</NativeDependenciesConfigurationUnix>
+ <NativeDependenciesConfigurationUnix Condition=" '$(Configuration)' == 'Release' ">opt</NativeDependenciesConfigurationUnix>
+ <NativeDependenciesConfigurationUnix Condition=" '$(Configuration)' == 'ReleaseSigned' ">opt</NativeDependenciesConfigurationUnix>
+ </PropertyGroup>
+
+ <!-- Autodetect platform -->
+ <PropertyGroup Condition=" '$(OS)' != 'Unix' ">
+ <NativeDepsPlatform>Windows</NativeDepsPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(OS)' == 'Unix' And Exists('/Applications') And Exists('/Library') And Exists('/System') ">
+ <NativeDepsPlatform>Mac</NativeDepsPlatform>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(OS)' == 'Unix' And '$(NativeDepsPlatform)' == '' ">
+ <NativeDepsPlatform>Linux</NativeDepsPlatform>
+ </PropertyGroup>
+
+ <Import Project="NativeDeps.$(NativeDepsPlatform).targets" />
+</Project> \ No newline at end of file