Megosztás a következőn keresztül:


Forráslétrehozás platformhívásokhoz

A .NET 7 egy forrásgenerátort vezet be a P/Invokes számára, amely felismeri a LibraryImportAttribute C# kódban található kódot.

Ha nem a forrásgenerálást használja, a .NET-futtatókörnyezet beépített interop rendszere létrehoz egy IL-csonkot – egy JIT-ed nevű IL-utasításfolyamot –, amely megkönnyíti a felügyeltről a nem felügyeltre való áttérést. Az alábbi kód az ezt a mechanizmust használó P/Invoke definícióját és meghívását mutatja be:

[DllImport(
    "nativelib",
    EntryPoint = "to_lower",
    CharSet = CharSet.Unicode)]
internal static extern string ToLower(string str);

// string lower = ToLower("StringToConvert");

Az IL-csonk kezeli a paraméterek rendezését és az értékek visszaadását, és meghívja a nem felügyelt kódot, miközben tiszteletben tartja azokat a DllImportAttribute beállításokat, amelyek befolyásolják a nem felügyelt kód meghívását (például SetLastError). Mivel ez az IL-csonk futásidőben jön létre, nem érhető el az idő előtti (AOT) fordítóhoz vagy az IL-vágási forgatókönyvekhez. Az IL generációja fontos költséget jelent a rendezéshez. Ez a költség az alkalmazások teljesítménye és a potenciális célplatformok támogatása szempontjából mérhető, amelyek nem teszik lehetővé a dinamikus kódlétrehozást. A natív AOT-alkalmazásmodell a dinamikus kódlétrehozással kapcsolatos problémákat úgy oldja meg, hogy előre lefordítja az összes kódot közvetlenül a natív kódba. Az olyan DllImport platformok használata, amelyek teljes Natív AOT-forgatókönyveket igényelnek, ezért más megközelítések (például forrásgenerálás) használata megfelelőbb. A rendezési logika DllImport hibakeresése forgatókönyvekben szintén nem triviális gyakorlat.

A .NET 7 SDK-hoz mellékelt és alapértelmezés szerint engedélyezett P/Invoke forrásgenerátor olyan LibraryImportAttribute és static metódust kerespartial, amely elindítja a fordítási kód fordítási idejének forrását, így nincs szükség az IL-csonk futásidőben történő létrehozására, és lehetővé teszi a P/Invoke beágyazott használatát. A beépített rendszerről a forrásgenerátorra való migráláshoz és általában a használathoz elemzőket és kódjavítókat is tartalmaz.

Alapszintű használat

A LibraryImportAttribute kialakítás a használathoz DllImportAttribute hasonló. Az előző példában a P/Invoke forrásgenerálást használhatjuk úgy, hogy a metódust LibraryImportAttribute a partial következő helyett externjelöljük meg:

[LibraryImport(
    "nativelib",
    EntryPoint = "to_lower",
    StringMarshalling = StringMarshalling.Utf16)]
internal static partial string ToLower(string str);

A fordítás során a forrásgenerátor elindítja a ToLower paraméter rendezését kezelő metódus implementációját, és UTF-16-ként adja vissza az string értéket. Mivel a rendezés már létrehozott forráskódot, a hibakeresők logikáját tekintheti át, és végiglépkedhet rajta.

MarshalAs

A forrásgenerátor a MarshalAsAttribute. Az előző kód a következőképpen is írható:

[LibraryImport(
    "nativelib",
    EntryPoint = "to_lower")]
[return: MarshalAs(UnmanagedType.LPWStr)]
internal static partial string ToLower(
    [MarshalAs(UnmanagedType.LPWStr)] string str);

Bizonyos beállítások MarshalAsAttribute nem támogatottak. Ha nem támogatott beállításokat próbál használni, a forrásgenerátor hibát fog kibocsátani. További információt a DllImport eltérései című témakörben talál.

Hívási konvenció

A hívási konvenció megadásához használja UnmanagedCallConvAttributepéldául a következőt:

[LibraryImport(
    "nativelib",
    EntryPoint = "to_lower",
    StringMarshalling = StringMarshalling.Utf16)]
[UnmanagedCallConv(
    CallConvs = new[] { typeof(CallConvStdcall) })]
internal static partial string ToLower(string str);

Különbségek a DllImport

LibraryImportAttribute célja, hogy a legtöbb esetben egyszerű átalakítás DllImportAttribute legyen, de vannak szándékos változások:

  • CallingConvention nincs megfelelője a következőn: LibraryImportAttribute. UnmanagedCallConvAttribute helyett.
  • CharSet (for CharSet) a következőre cserélték: StringMarshalling (for StringMarshalling). Az ANSI el lett távolítva, és az UTF-8 már elérhető első osztályú lehetőségként.
  • BestFitMapping és ThrowOnUnmappableChar nincs megfelelője. Ezek a mezők csak akkor voltak relevánsak, amikor ANSI-sztringet rendeztek Windows rendszeren. Az ANSI-sztringek rendezéséhez létrehozott kód az és a BestFitMapping=falseThrowOnUnmappableChar=false.
  • ExactSpelling nincs egyenértékű. Ez a mező Egy Windows-központú beállítás volt, és nem volt hatással a nem Windows operációs rendszerekre. A metódusnévnek vagy EntryPoint a belépési pont nevének pontos helyesírásának kell lennie. Ez a mező a Win32-programozásban használt utótagokhoz és A utótagokhozW előzményalapú felhasználást használ.
  • PreserveSig nincs egyenértékű. Ez a mező egy Windows-központú beállítás volt. A létrehozott kód mindig közvetlenül fordítja le az aláírást.
  • A projektet nem biztonságosként kell megjelölni az AllowUnsafeBlocks használatával.

Bizonyos beállítások MarshalAsAttributetámogatása, bizonyos típusok alapértelmezett rendezése és más, az interophoz kapcsolódó attribútumok támogatása is eltérő. További információkért tekintse meg a kompatibilitási különbségekről szóló dokumentációnkat.

Lásd még