From 7b658c56acd83aea8657f4982c6f5279f7884426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20de=20S=C3=A9r=C3=A9sin?= Date: Sun, 21 Jan 2024 19:46:05 +0100 Subject: [PATCH] Support AOT --- src/Confluent.Kafka/Impl/LibRdKafka.cs | 69 ++++++++++++++++----- src/Confluent.Kafka/Impl/SafeKafkaHandle.cs | 2 +- src/Confluent.Kafka/Internal/Util.cs | 9 ++- 3 files changed, 62 insertions(+), 18 deletions(-) diff --git a/src/Confluent.Kafka/Impl/LibRdKafka.cs b/src/Confluent.Kafka/Impl/LibRdKafka.cs index 574773676..066d3a9fa 100644 --- a/src/Confluent.Kafka/Impl/LibRdKafka.cs +++ b/src/Confluent.Kafka/Impl/LibRdKafka.cs @@ -29,6 +29,9 @@ #if NET462 using System.ComponentModel; #endif +#if NET5_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif namespace Confluent.Kafka.Impl @@ -171,7 +174,11 @@ public static string LastError } } - static bool SetDelegates(Type nativeMethodsClass) + static bool SetDelegates( +#if NET5_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] +#endif + Type nativeMethodsClass) { var methods = nativeMethodsClass.GetRuntimeMethods().ToArray(); @@ -662,14 +669,45 @@ private static void LoadNetFrameworkDelegates(string userSpecifiedPath) #endif - private static bool TrySetDelegates(List nativeMethodCandidateTypes) + private static bool TrySetDelegates( +#if NET5_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] +#endif + Type nativeMethodCandidateType) { - foreach (var t in nativeMethodCandidateTypes) + if (SetDelegates(nativeMethodCandidateType)) { - if (SetDelegates(t)) - { - return true; - } + return true; + } + + throw new DllNotFoundException("Failed to load the librdkafka native library."); + } + + private static bool TrySetDelegates( +#if NET5_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] +#endif + Type nativeMethodCandidateType1, +#if NET5_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] +#endif + Type nativeMethodCandidateType2, +#if NET5_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicMethods | DynamicallyAccessedMemberTypes.NonPublicMethods)] +#endif + Type nativeMethodCandidateType3) + { + if (SetDelegates(nativeMethodCandidateType1)) + { + return true; + } + if (SetDelegates(nativeMethodCandidateType2)) + { + return true; + } + if (SetDelegates(nativeMethodCandidateType3)) + { + return true; } throw new DllNotFoundException("Failed to load the librdkafka native library."); @@ -687,7 +725,7 @@ private static void LoadNetStandardDelegates(string userSpecifiedPath) } } - TrySetDelegates(new List { typeof(NativeMethods.NativeMethods) }); + TrySetDelegates(typeof(NativeMethods.NativeMethods)); } private static void LoadOSXDelegates(string userSpecifiedPath) @@ -700,7 +738,7 @@ private static void LoadOSXDelegates(string userSpecifiedPath) } } - TrySetDelegates(new List { typeof(NativeMethods.NativeMethods) }); + TrySetDelegates(typeof(NativeMethods.NativeMethods)); } private static void LoadLinuxDelegates(string userSpecifiedPath) @@ -712,7 +750,7 @@ private static void LoadLinuxDelegates(string userSpecifiedPath) throw new InvalidOperationException($"Failed to load librdkafka at location '{userSpecifiedPath}'. dlerror: '{PosixNative.LastError}'."); } - TrySetDelegates(new List { typeof(NativeMethods.NativeMethods) }); + TrySetDelegates(typeof(NativeMethods.NativeMethods)); } else { @@ -721,16 +759,15 @@ private static void LoadLinuxDelegates(string userSpecifiedPath) var osName = PlatformApis.GetOSName(); if (osName.Equals("alpine", StringComparison.OrdinalIgnoreCase)) { - delegates.Add(typeof(NativeMethods.NativeMethods_Alpine)); + TrySetDelegates(typeof(NativeMethods.NativeMethods_Alpine)); } else { - delegates.Add(typeof(NativeMethods.NativeMethods_Centos7)); - delegates.Add(typeof(NativeMethods.NativeMethods)); - delegates.Add(typeof(NativeMethods.NativeMethods_Centos6)); + TrySetDelegates( + typeof(NativeMethods.NativeMethods_Centos7), + typeof(NativeMethods.NativeMethods), + typeof(NativeMethods.NativeMethods_Centos6)); } - - TrySetDelegates(delegates); } } diff --git a/src/Confluent.Kafka/Impl/SafeKafkaHandle.cs b/src/Confluent.Kafka/Impl/SafeKafkaHandle.cs index bd553b304..eb49f288a 100644 --- a/src/Confluent.Kafka/Impl/SafeKafkaHandle.cs +++ b/src/Confluent.Kafka/Impl/SafeKafkaHandle.cs @@ -1810,7 +1810,7 @@ internal void DeleteConsumerGroupOffsets(String group, IEnumerable tp.Topic == null || tp.Partition == null).Count() > 0) + if (partitions.Where(tp => tp.Topic == null).Count() > 0) { throw new ArgumentException("Cannot delete offsets because one or more topics or partitions were specified as null."); } diff --git a/src/Confluent.Kafka/Internal/Util.cs b/src/Confluent.Kafka/Internal/Util.cs index 9647bbdaa..53b9edb21 100644 --- a/src/Confluent.Kafka/Internal/Util.cs +++ b/src/Confluent.Kafka/Internal/Util.cs @@ -19,6 +19,9 @@ using SystemMarshal = System.Runtime.InteropServices.Marshal; using SystemGCHandle = System.Runtime.InteropServices.GCHandle; using SystemGCHandleType = System.Runtime.InteropServices.GCHandleType; +#if NET5_0_OR_GREATER +using System.Diagnostics.CodeAnalysis; +#endif namespace Confluent.Kafka.Internal @@ -79,7 +82,11 @@ public unsafe static string PtrToStringUTF8(IntPtr strPtr, UIntPtr strLength) return Encoding.UTF8.GetString((byte*)strPtr.ToPointer(), (int)strLength); } - public static T PtrToStructure(IntPtr ptr) + public static T PtrToStructure< +#if NET5_0_OR_GREATER + [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] +#endif + T>(IntPtr ptr) { return SystemMarshal.PtrToStructure(ptr); }