Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
.NET 7 zavádí generátor zdrojů pro volání nespravovaného LibraryImportAttribute kódu v jazyce C#.
Pokud nepoužívá generování zdrojového kódu, integrovaný systém interoperability v modulu runtime .NET generuje zástupný kód IL – tok instrukcí IL, který je za běhu just-in-time kompilován – pro usnadnění přechodu ze spravovaného na nespravované prostředí. Následující kód ukazuje definování a následné volání nespravovaného kódu, který používá tento mechanismus:
[DllImport(
"nativelib",
EntryPoint = "to_lower",
CharSet = CharSet.Unicode)]
internal static extern string ToLower(string str);
// string lower = ToLower("StringToConvert");
Zástupný kód IL zpracovává zařazování parametrů a návratové hodnoty a volá nespravovaný kód při zachování nastavení DllImportAttribute , která ovlivňují způsob vyvolání nespravovaného kódu (například SetLastError). Vzhledem k tomu, že se tento zástupný kód IL generuje za běhu, není k dispozici pro scénáře ahead-of-time (AOT) kompilátoru nebo ořezávání IL. Generování IL představuje důležité náklady, které je třeba zvážit při zařazování. Tyto náklady je možné měřit z hlediska výkonu aplikace a podpory potenciálních cílových platforem, které neumožňují dynamické generování kódu. Nativní aplikační model AOT řeší problémy s dynamickým generováním kódu předkompilováním veškerého kódu předem přímo do nativního kódu. Použití DllImport není možnost pro platformy, které vyžadují úplné nativní scénáře AOT, a proto je vhodnější použít jiné přístupy (například generování zdroje). Ladění logiky zařazování ve DllImport scénářích je také netiktivní cvičení.
Generátor kódu P/Invoke, který je součástí sady .NET 7 SDK a je ve výchozím nastavení povolen, hledá LibraryImportAttribute na static a partial metodu pro aktivaci generování kódu pro marshalingu během kompilace, čímž se eliminuje potřeba generování zástupných procedur IL za běhu a umožňuje volání P/Invoke inline.
Analyzátory a opravy kódu jsou také zahrnuty, aby pomohly s migrací z integrovaného systému do generátoru zdrojů a obecně s využitím.
Základní použití
Tato LibraryImportAttribute funkce je navržená tak, aby byla podobná DllImportAttribute použití. Předchozí příklad můžeme převést na použití generování zdroje P/Invoke pomocí LibraryImportAttribute metody a označení metody jakopartial:extern
[LibraryImport(
"nativelib",
EntryPoint = "to_lower",
StringMarshalling = StringMarshalling.Utf16)]
internal static partial string ToLower(string str);
Během kompilace se spustí generátor zdroje, který vygeneruje implementaci ToLower metody, která zpracovává zařazování parametru string a návratovou hodnotu jako UTF-16. Vzhledem k tomu, že se teď vygeneruje zdrojový kód, můžete se na logiku v ladicím programu podívat a projít si ji.
MarshalAs
Zdroj generátoru také MarshalAsAttributerespektuje . Předchozí kód lze také napsat takto:
[LibraryImport(
"nativelib",
EntryPoint = "to_lower")]
[return: MarshalAs(UnmanagedType.LPWStr)]
internal static partial string ToLower(
[MarshalAs(UnmanagedType.LPWStr)] string str);
Některá nastavení MarshalAsAttribute nejsou podporovaná. Pokud se pokusíte použít nepodporovaná nastavení, generátor zdroje vygeneruje chybu. Další informace naleznete v tématu Rozdíly z knihovny DllImport.
Konvenci
Pokud chcete zadat konvenci volání, použijte UnmanagedCallConvAttributenapříklad:
[LibraryImport(
"nativelib",
EntryPoint = "to_lower",
StringMarshalling = StringMarshalling.Utf16)]
[UnmanagedCallConv(
CallConvs = new[] { typeof(CallConvStdcall) })]
internal static partial string ToLower(string str);
Rozdíly od DllImport
LibraryImportAttribute má být ve většině případů jednoduchým převodem DllImportAttribute , ale existují některé záměrné změny:
- CallingConvention nemá žádný ekvivalent dne LibraryImportAttribute. UnmanagedCallConvAttribute místo toho by se měla použít.
- CharSet (pro CharSet) byla nahrazena písmenem StringMarshalling (pro StringMarshalling). ANSI byl odebrán a UTF-8 je nyní k dispozici jako prvotřídní možnost.
-
BestFitMapping a ThrowOnUnmappableChar nemají žádný ekvivalent. Tato pole byla relevantní pouze při zařazování řetězce ANSI ve Windows. Vygenerovaný kód pro zařazování řetězce ANSI bude mít ekvivalentní chování
BestFitMapping=falseaThrowOnUnmappableChar=false. -
ExactSpelling nemá žádný ekvivalent. Toto pole bylo nastavení zaměřené na Windows a nemělo žádný vliv na operační systémy jiné než Windows. Název metody nebo EntryPoint by měl být přesným pravopisem názvu vstupního bodu. Toto pole má historické použití související s
Apříponami aWpříponami používanými v programování win32. - PreserveSig nemá žádný ekvivalent. Toto pole bylo nastavení zaměřené na Windows. Vygenerovaný kód vždy přímo přeloží podpis.
- Projekt musí být označený jako nebezpečný pomocí AllowUnsafeBlocks.
Existují také rozdíly v podpoře některých nastavení MarshalAsAttribute, výchozí zařazování určitých typů a dalších atributů souvisejících s interoperabilitou. Další informace najdete v naší dokumentaci k rozdílům v kompatibilitě.