Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
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 extern
jelö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=false
ThrowOnUnmappableChar=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.