Platform çağrıları için kaynak oluşturma
.NET 7, C# kodunda değerini tanıyan P/Invoke'lar LibraryImportAttribute için bir kaynak oluşturucu sunar.
Kaynak oluşturma kullanmadığında, .NET çalışma zamanındaki yerleşik birlikte çalışma sistemi, yönetilenden yönetilmeyene geçişi kolaylaştırmak için çalışma zamanında bir IL saplaması (JIT-ed olan bir IL yönergeleri akışı) oluşturur. Aşağıdaki kod, bu mekanizmayı kullanan bir P/Invoke tanımlamayı ve çağırmayı gösterir:
[DllImport(
"nativelib",
EntryPoint = "to_lower",
CharSet = CharSet.Unicode)]
internal static extern string ToLower(string str);
// string lower = ToLower("StringToConvert");
IL saplama, parametrelerin ve dönüş değerlerinin sıralanmasıyla ilgilenir ve yönetilmeyen kodu çağırırken, yönetilmeyen kodun nasıl çağrılması gerektiğini etkileyen ayarlara DllImportAttribute riayete eder (örneğin, SetLastError). Bu IL saplaması çalışma zamanında oluşturulduğundan, önceden (AOT) derleyici veya IL kırpma senaryoları için kullanılamaz. IL'nin oluşturulması, marshalling için dikkate alınması gereken önemli bir maliyeti temsil eder. Bu maliyet, dinamik kod oluşturulmasına izin vermeyebilir olası hedef platformlar için uygulama performansı ve destek açısından ölçülebilir. Yerel AOT uygulama modeli, tüm kodları önceden doğrudan yerel koda önceden derleyerek dinamik kod oluşturmayla ilgili sorunları giderir. Kullanmak DllImport
, tam Yerel AOT senaryoları gerektiren platformlar için bir seçenek değildir ve bu nedenle diğer yaklaşımları (örneğin, kaynak oluşturma) kullanmak daha uygundur. Senaryolarda sıralama mantığında DllImport
hata ayıklamak da önemsiz olmayan bir alıştırmadır.
.NET 7 SDK'sına dahil edilen ve varsayılan olarak etkinleştirilen P/Invoke kaynak oluşturucusu, derleme zamanı kaynak oluşturmasını tetikleyen bir static
ve partial
yöntemini arar LibraryImportAttribute ve çalışma zamanında IL saplaması oluşturma gereksinimini ortadan kaldırır ve P/Invoke'un satır içi olarak oluşturulmasını sağlar. Çözümleyiciler ve kod düzelticiler, yerleşik sistemden kaynak oluşturucuya ve genel kullanımla geçişe yardımcı olmak için de dahil edilir.
Temel kullanım
LibraryImportAttribute, kullanımdakine benzer şekilde DllImportAttribute tasarlanmıştır. önceki örneği P/Invoke kaynak oluşturmayı LibraryImportAttribute kullanmak için dönüştürmek için yöntemini yerine ve olarak partial
extern
işaretleyebiliriz:
[LibraryImport(
"nativelib",
EntryPoint = "to_lower",
StringMarshalling = StringMarshalling.Utf16)]
internal static partial string ToLower(string str);
Derleme sırasında kaynak oluşturucu, parametrenin ToLower
sıralanması ve değeri UTF-16 olarak döndüren yöntemin string
bir uygulamasını oluşturmak için tetiklenir. Artık sıralama kaynak kodu oluşturulduğundan, bir hata ayıklayıcıda mantığa bakabilir ve bu mantıkta adım adım ilerleyebilirsiniz.
MarshalAs
Kaynak oluşturucu ayrıca öğesine de saygı gösterir MarshalAsAttribute. Yukarıdaki kod şu şekilde de yazılabilir:
[LibraryImport(
"nativelib",
EntryPoint = "to_lower")]
[return: MarshalAs(UnmanagedType.LPWStr)]
internal static partial string ToLower(
[MarshalAs(UnmanagedType.LPWStr)] string str);
için bazı ayarlar MarshalAsAttribute desteklenmez. Desteklenmeyen ayarları kullanmaya çalışırsanız kaynak oluşturucu bir hata yayar. Daha fazla bilgi için bkz . DllImport'tan farklar.
Çağırma kuralı
Çağırma kuralını belirtmek için kullanın UnmanagedCallConvAttribute, örneğin:
[LibraryImport(
"nativelib",
EntryPoint = "to_lower",
StringMarshalling = StringMarshalling.Utf16)]
[UnmanagedCallConv(
CallConvs = new[] { typeof(CallConvStdcall) })]
internal static partial string ToLower(string str);
Arasındaki farklar DllImport
LibraryImportAttribute çoğu durumda basit bir dönüştürme DllImportAttribute olarak tasarlanmıştır, ancak bazı kasıtlı değişiklikler vardır:
- CallingConvention üzerinde LibraryImportAttributeeşdeğeri yoktur. UnmanagedCallConvAttribute yerine kullanılmalıdır.
- CharSet(için CharSet) (içinStringMarshalling) ile StringMarshalling değiştirildi. ANSI kaldırıldı ve UTF-8 artık birinci sınıf bir seçenek olarak kullanılabilir.
- BestFitMapping ve ThrowOnUnmappableChar eşdeğeri yoktur. Bu alanlar yalnızca Windows'da ansi dizesinin hazırlaması sırasında geçerlidir. ANSI dizesini sıralamak için oluşturulan kod ile eşdeğer davranışa
BestFitMapping=false
ThrowOnUnmappableChar=false
sahip olur. - ExactSpelling eşdeğeri yoktur. Bu alan Windows merkezli bir ayardı ve Windows dışı işletim sistemleri üzerinde hiçbir etkisi yoktu. Yöntem adı veya EntryPoint giriş noktası adının tam yazımı olmalıdır. Bu alan, Win32 programlamasında kullanılan ve
W
sonekleri ile ilgiliA
geçmiş kullanımlara sahiptir. - PreserveSig eşdeğeri yoktur. Bu alan Windows merkezli bir ayardı. Oluşturulan kod her zaman doğrudan imzayı çevirir.
- Proje AllowUnsafeBlocks kullanılarak güvenli değil olarak işaretlenmelidir.
üzerinde bazı ayarların MarshalAsAttributedesteklenmesinde, belirli türlerin varsayılan olarak sıralanmasında ve birlikte çalışmayla ilgili diğer özniteliklerde de farklılıklar vardır. Daha fazla bilgi için uyumluluk farklılıklarıyla ilgili belgelerimize bakın.