diff --git a/src/Confluent.Kafka/Impl/LibRdKafka.cs b/src/Confluent.Kafka/Impl/LibRdKafka.cs index 9f2fc4970..1255e0547 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 @@ -173,7 +176,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(); @@ -673,14 +680,37 @@ 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 (SetDelegates(nativeMethodCandidateType1)) + { + return true; + } + if (SetDelegates(nativeMethodCandidateType2)) + { + return true; } throw new DllNotFoundException("Failed to load the librdkafka native library."); @@ -698,7 +728,7 @@ private static void LoadNetStandardDelegates(string userSpecifiedPath) } } - TrySetDelegates(new List { typeof(NativeMethods.NativeMethods) }); + TrySetDelegates(typeof(NativeMethods.NativeMethods)); } private static void LoadOSXDelegates(string userSpecifiedPath) @@ -711,7 +741,7 @@ private static void LoadOSXDelegates(string userSpecifiedPath) } } - TrySetDelegates(new List { typeof(NativeMethods.NativeMethods) }); + TrySetDelegates(typeof(NativeMethods.NativeMethods)); } private static void LoadLinuxDelegates(string userSpecifiedPath) @@ -723,7 +753,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 { @@ -732,17 +762,16 @@ 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 { // Try to load first the shared library with GSSAPI linkage // and then the one without. - delegates.Add(typeof(NativeMethods.NativeMethods)); - delegates.Add(typeof(NativeMethods.NativeMethods_Centos8)); + TrySetDelegates( + typeof(NativeMethods.NativeMethods), + typeof(NativeMethods.NativeMethods_Centos8)); } - - TrySetDelegates(delegates); } } diff --git a/src/Confluent.Kafka/Impl/SafeKafkaHandle.cs b/src/Confluent.Kafka/Impl/SafeKafkaHandle.cs index 375b7f3dc..60d0e34ba 100644 --- a/src/Confluent.Kafka/Impl/SafeKafkaHandle.cs +++ b/src/Confluent.Kafka/Impl/SafeKafkaHandle.cs @@ -1819,7 +1819,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); }