Closed landerverhacklansweeper closed 1 month ago
The problem could be fixed by writing the same logic without reflection inside a #if NET6_0_OR_GREATER
, while keeping the old logic for backward compatibility in the #else
block, then compiling the library for .NET standard, .NET 6 and 8
PR welcome if someone wants to take a swing at this.
I would if I could, but I'm not a contributer. Here is the required code.
// Copyright 2021 Ayoub Kaanich <kayoub5@live.com>
// SPDX-License-Identifier: MIT
using System;
using System.Reflection;
using System.Runtime.InteropServices;
namespace SharpPcap.LibPcap
{
class NativeLibraryHelper
{
#if NET6_0_OR_GREATER
public static void SetDllImportResolver(Assembly assembly, DllImportResolver resolver)
{
NativeLibrary.SetDllImportResolver(assembly, resolver);
}
public static bool TryLoad(string libraryPath, out IntPtr handle)
{
return NativeLibrary.TryLoad(libraryPath, out handle);
}
#else
public delegate IntPtr DllImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath);
private static readonly Type NativeLibraryType;
static NativeLibraryHelper()
{
NativeLibraryType = typeof(DllImportSearchPath).Assembly
.GetType("System.Runtime.InteropServices.NativeLibrary");
}
public static void SetDllImportResolver(Assembly assembly, DllImportResolver resolver)
{
if (NativeLibraryType == null)
{
return;
}
var dllImportResolverType = typeof(DllImportSearchPath).Assembly
.GetType("System.Runtime.InteropServices.DllImportResolver");
var setDllImportResolverMethod = NativeLibraryType
.GetMethod(
"SetDllImportResolver",
BindingFlags.Public | BindingFlags.Static,
null,
new[] { typeof(Assembly), dllImportResolverType },
null
);
setDllImportResolverMethod.Invoke(null, new object[] {
assembly,
Delegate.CreateDelegate(dllImportResolverType, resolver, "Invoke")
});
}
public static bool TryLoad(string libraryPath, out IntPtr handle)
{
var tryLoadMethod = NativeLibraryType
?.GetMethod(
"TryLoad",
BindingFlags.Public | BindingFlags.Static,
null,
new[] { typeof(string), typeof(IntPtr).MakeByRefType() },
null
);
if (tryLoadMethod == null)
{
handle = IntPtr.Zero;
return false;
}
var args = new object[] { libraryPath, IntPtr.Zero };
var res = (bool)tryLoadMethod.Invoke(null, args);
handle = (IntPtr)args[1];
return res;
}
#endif
}
}
I recently got an issue using SharpPcap 9.0.0 on linux-x64 (.NET 8.0). It would not load correctly until I turned off Trimming during publish. The culprit is the following class: NativeLibraryHelper.
For some reason, it uses reflection to get the
SetDllImportResolver
method of theNativeLibrary
class inSystem.Runtime.InteropServices
. Because of this, the compiler is unaware of this dependency. Can we add something likeSo the trimming would not throw out this required method?
I added this to my own method, and it does seem to work.
I have no idea why
NativeLibraryHelper
uses reflection, but whatever the reason, it might also be the reason why this attribute might not be set.Could we avoid the reflection all together? It also hinders my plan to use AOT. I want to be able to run on weaker hardware.