Natív kódtár betöltése
Ez a cikk bemutatja, hogy a futtatókörnyezet mely útvonalakon keres natív kódtárak P/Invoke használatával való betöltésekor. Azt is bemutatja, hogyan kell használni SetDllImportResolver.
Kódtárnév-változatok
A platformfüggetlen P/Invoke kód egyszerűbb megkönnyítése érdekében a futtatókörnyezet hozzáadja a canonical shared library bővítményt (.dll
.so
vagy .dylib
) a natív kódtárnevekhez. Unix-alapú platformokon a futtatókörnyezet is megpróbálja az előfeltűnést lib
. Ezek a kódtárnevek-változatok automatikusan keresnek, amikor natív kódtárakat töltő API-kat használ, például DllImportAttribute.
Feljegyzés
A kódtárnevek abszolút elérési útjai (például ) a következőképpen vannak kezelve, /usr/lib/libc.so
és a rendszer nem keres változatokat.
Vegye figyelembe a P/Invoke használatát az alábbi példában:
[DllImport("nativedep")]
static extern int ExportedFunction();
Windows rendszeren való futtatáskor a DLL a következő sorrendben lesz keresve:
nativedep
nativedep.dll
(ha az erőforrástár neve még nem végződik vagy.dll
.exe
)
Linux vagy macOS rendszeren való futtatáskor a futtatókörnyezet megpróbálja előre felerősíteni lib
és hozzáfűzni a canonical megosztott kódtárbővítményt. Ezeken az operációs rendszereken a kódtárnév-változatok a következő sorrendben próbálkoznak:
nativedep.so
/nativedep.dylib
libnativedep.so
/libnativedep.dylib
1nativedep
libnativedep
1
Linuxon a keresési sorrend eltérő, ha a kódtár neve végződik .so
vagy tartalmaz .so.
(jegyezze fel a zárót .
). Vegyük a következő példát:
[DllImport("nativedep.so.6")]
static extern int ExportedFunction();
Ebben az esetben a kódtárnév-változatok a következő sorrendben próbálkoznak:
nativedep.so.6
libnativedep.so.6
1nativedep.so.6.so
libnativedep.so.6.so
1
1 Az elérési út csak akkor van bejelölve, ha az erőforrástár neve nem tartalmaz könyvtárelválasztó karaktert (/
).
Egyéni importálási feloldó
Összetettebb esetekben a DLL-importálások futásidőben történő feloldására is használható SetDllImportResolver . Az alábbi példában a rendszer feloldja, nativedep
hogy nativedep_avx2
a processzor támogatja-e.
Tipp.
Ez a funkció csak a .NET Core 3.1-ben és a .NET 5+-ban érhető el.
using System;
using System.Reflection;
using System.Runtime.InteropServices;
namespace PInvokeSamples
{
public static partial class Program
{
[LibraryImport("nativedep")]
private static partial int ExportedFunction();
public static void Main(string[] args)
{
// Register the import resolver before calling the imported function.
// Only one import resolver can be set for a given assembly.
NativeLibrary.SetDllImportResolver(Assembly.GetExecutingAssembly(), DllImportResolver);
int value = ExportedFunction();
Console.WriteLine(value);
}
private static IntPtr DllImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
{
if (libraryName == "nativedep")
{
// On systems with AVX2 support, load a different library.
if (System.Runtime.Intrinsics.X86.Avx2.IsSupported)
{
return NativeLibrary.Load("nativedep_avx2", assembly, searchPath);
}
}
// Otherwise, fallback to default import resolver.
return IntPtr.Zero;
}
}
}
Lásd még
Visszajelzés
https://aka.ms/ContentUserFeedback.
Hamarosan elérhető: 2024-ben fokozatosan kivezetjük a GitHub-problémákat a tartalom visszajelzési mechanizmusaként, és lecseréljük egy új visszajelzési rendszerre. További információ:Visszajelzés küldése és megtekintése a következőhöz: