Aracılığıyla paylaş


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 partialexterniş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=falseThrowOnUnmappableChar=falsesahip 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 ilgili A 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.

Ayrıca bkz.