Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
.NET 8, sizin için ComWrappers API'sinin bir uygulamasını oluşturan bir kaynak oluşturucuyu tanıtır . Jeneratör GeneratedComInterfaceAttribute öğesini tanır.
.NET çalışma zamanının yerleşik (kaynak oluşturulmamış) ve yalnızca Windows’a özel olan COM birlikte çalışma sistemi, yönetilen koddan COM’a ve tam tersi yöndeki geçişi kolaylaştırmak için çalışma zamanında JIT ile derlenen bir IL saplaması, yani IL yönergeleri akışı oluşturur. Bu IL saplaması çalışma zamanında oluşturulduğundan NativeAOT ve IL kırpma ile uyumlu değildir. Çalışma zamanında saplama oluşturma, marshalling sorunlarını tanılamayı da zorlaştırabilir.
Yerleşik birlikte çalışabilirlik, çalışma zamanında kod oluşturmayı gerektiren ComImport veya DllImport gibi öznitelikleri kullanır. Aşağıdaki kodda bunun bir örneği gösterilmektedir:
[ComImport]
interface IFoo
{
void Method(int i);
}
[DllImport("MyComObjectProvider")]
static nint GetPointerToComInterface(); // C definition - IUnknown* GetPointerToComInterface();
[DllImport("MyComObjectProvider")]
static void GivePointerToComInterface(nint comObject); // C definition - void GivePointerToComInterface(IUnknown* pUnk);
// Use the system to create a Runtime Callable Wrapper to use in managed code
nint ptr = GetPointerToComInterface();
IFoo foo = (IFoo)Marshal.GetObjectForIUnknown(ptr);
foo.Method(0);
...
// Use the system to create a COM Callable Wrapper to pass to unmanaged code
IFoo foo = GetManagedIFoo();
nint ptr = Marshal.GetIUnknownForObject(foo);
GivePointerToComInterface(ptr);
API, ComWrappers yerleşik COM sistemini kullanmadan C# dilinde COM ile etkileşime olanak tanır, ancak önemli miktarda şablon kod ve elle yazılmış güvensiz kod gerektirir. COM arabirim oluşturucu bu işlemi otomatikleştirir ve yerleşik COM kadar kolay hale getirir ComWrappers , ancak kırpılabilir ve AOT dostu bir şekilde sunar.
Temel kullanım
COM arabirim oluşturucuyu kullanmak için, COM'dan içeri aktarmak veya COM'a göstermek istediğiniz arabirim tanımına GeneratedComInterfaceAttribute ve GuidAttribute özniteliklerini ekleyin. Türün, oluşturulan kodun erişebilmesi için partial olarak işaretlenmesi ve internal veya public görünürlüğüne sahip olması zorunludur.
[GeneratedComInterface]
[Guid("3faca0d2-e7f1-4e9c-82a6-404fd6e0aab8")]
internal partial interface IFoo
{
void Method(int i);
}
Ardından, bir arabirimi uygulayan sınıfı COM'a açmak için GeneratedComClassAttribute etiketini uygulayan sınıfa ekleyin. Bu sınıf hem partial olmalı hem de internal veya public olmalıdır.
[GeneratedComClass]
internal partial class Foo : IFoo
{
public void Method(int i)
{
// Do things
}
}
Derleme zamanında, üreteç ComWrappers API'sinin bir uygulamasını oluşturur ve COM arabirimini kullanmak veya kullanıma açmak için StrategyBasedComWrappers türünü veya özel bir türetilmiş türü kullanabilirsiniz.
[LibraryImport("MyComObjectProvider")]
private static partial nint GetPointerToComInterface(); // C definition - IUnknown* GetPointerToComInterface();
[LibraryImport("MyComObjectProvider")]
private static partial void GivePointerToComInterface(nint comObject); // C definition - void GivePointerToComInterface(IUnknown* pUnk);
// Use the ComWrappers API to create a Runtime Callable Wrapper to use in managed code
ComWrappers cw = new StrategyBasedComWrappers();
nint ptr = GetPointerToComInterface();
IFoo foo = (IFoo)cw.GetOrCreateObjectForComInstance(ptr, CreateObjectFlags.None);
foo.Method(0);
...
// Use the system to create a COM Callable Wrapper to pass to unmanaged code
ComWrappers cw = new StrategyBasedComWrappers();
Foo foo = new();
nint ptr = cw.GetOrCreateComInterfaceForObject(foo, CreateComInterfaceFlags.None);
GivePointerToComInterface(ptr);
Sıralamayı özelleştirme
COM arabirim oluşturucu, MarshalUsingAttribute özniteliğini ve MarshalAsAttribute özniteliğinin bazı kullanımlarını, parametrelerin marshalingini özelleştirmek için dikkate alır. Daha fazla bilgi için MarshalUsing özniteliği ile kaynak tarafından üretilen hazırlamayı özelleştirmeyi ve MarshalAs özniteliği ile parametre hazırlamayı özelleştirmeyi nasıl yapacağınızı inceleyin.
GeneratedComInterfaceAttribute.StringMarshalling ve GeneratedComInterfaceAttribute.StringMarshallingCustomType özellikleri, diğer marshalling özniteliklerine sahip değillerse, arabirimdeki string türündeki tüm parametreler ve dönüş türleri için geçerlidir.
Örtük HRESULTs ve PreserveSig
C# içindeki COM yöntemleri, yerel yöntemlerden farklı bir imzaya sahiptir. Standart COM, hata ve başarı durumlarını HRESULTtemsil eden 4 baytlık tamsayı türünde bir dönüş türüne sahiptir. Bu HRESULT dönüş değeri varsayılan olarak C# imzasında gizlenir ve bir hata değeri döndürüldüğünde özel duruma dönüştürülür. Yerel COM imzasının son "out" parametresi isteğe bağlı olarak C# imzasında dönüşe dönüştürülebilir.
Örneğin, aşağıdaki kod parçacıkları C# metot imzalarını ve oluşturucunun çıkardığı ilgili yerel imzayı gösterir.
void Method1(int i);
int Method2(float i);
HRESULT Method1(int i);
HRESULT Method2(float i, _Out_ int* returnValue);
Kendiniz HRESULT işlemek istiyorsanız, oluşturucunun bu dönüşümü yapmaması gerektiğini belirtmek için yönteme PreserveSigAttribute ekleyebilirsiniz. Oluşturucu [PreserveSig] uygulandığında hangi yerel imzanın beklendiğini aşağıdaki kod parçacıkları gösterir. COM yöntemleri HRESULT döndürmelidir, bu nedenle PreserveSig içeren herhangi bir yöntemin dönüş değeri int olmalıdır.
[PreserveSig]
int Method1(int i, out int j);
[PreserveSig]
int Method2(float i);
HRESULT Method1(int i, int* j);
HRESULT Method2(float i);
Daha fazla bilgi için .NET birlikte çalışmadaki örtük yöntem imza çevirilerinikısmına bakın.
Yerleşik COM ile uyumsuzluklar ve farklılıklar
IUnknown sadece
Desteklenen tek arabirim tabanıdır IUnknown.
InterfaceTypeAttribute dışında bir değere sahip arabirimler, kaynak üretili COM'da desteklenmez.
InterfaceTypeAttribute içermeyen herhangi bir arabirimin IUnknown'den türetilmiş olduğu varsayılır. Bu, varsayılanın InterfaceIsDualolduğu yerleşik COM'dan farklıdır.
Varsayılan ayarları ve desteği düzenleme
Kaynak tarafından oluşturulan COM,yerleşik COM'dan bazı farklı varsayılan sıralama davranışlarına sahiptir.
Yerleşik COM sisteminde, örtük
[In]özniteliklere sahip olan blittable öğe dizileri dışında tüm türler örtük[In, Out]bir özniteliğe sahiptir. Kaynak tarafından oluşturulan COM'da, blittable öğe dizileri de dahil olmak üzere tüm türler[In]semantiğine sahiptir.[In]ve[Out]özniteliklerine yalnızca dizilerde izin verilir. Diğer türlerde[Out]veya[In, Out]davranışı gerekiyorsa,inveoutparametre değiştiricilerini kullanın.
Türetilmiş arabirimler
Yerleşik COM sisteminde, diğer COM arabirimlerinden türetilen arabirimleriniz varsa, anahtar sözcüğüyle new temel arabirimlerde her temel yöntem için bir gölgelendirme yöntemi bildirmeniz gerekir. Daha fazla bilgi için COM arabirimi devralma ve .NET'e bkz.
[ComImport]
[Guid("3faca0d2-e7f1-4e9c-82a6-404fd6e0aab8")]
interface IBase
{
void Method1(int i);
void Method2(float i);
}
[ComImport]
[Guid("3faca0d2-e7f1-4e9c-82a6-404fd6e0aab8")]
interface IDerived : IBase
{
new void Method1(int i);
new void Method2(float f);
void Method3(long l);
void Method4(double d);
}
COM arabirim oluşturucu, temel yöntemlerin gölgelendirmesini beklemez. Başka bir arabirimden devralan bir yöntem oluşturmak için, temel arabirimi bir C# temel arabirimi olarak belirtmeniz ve türetilmiş arabirimin yöntemlerini eklemeniz yeterlidir. Daha fazla bilgi için tasarım belgesine bakın.
[GeneratedComInterface]
[Guid("3faca0d2-e7f1-4e9c-82a6-404fd6e0aab8")]
interface IBase
{
void Method1(int i);
void Method2(float i);
}
[GeneratedComInterface]
[Guid("3faca0d2-e7f1-4e9c-82a6-404fd6e0aab8")]
interface IDerived : IBase
{
void Method3(long l);
void Method4(double d);
}
GeneratedComInterface özniteliğine sahip bir arabirimin, yalnızca GeneratedComInterface özniteliği olan bir temel arabirimden devralabileceğini unutmayın.
Derleme sınırları boyunca türetilmiş arabirimler
.NET 8'de, başka bir derlemede tanımlanmış olan GeneratedComInterface özniteliğine sahip bir arabirimden türeyen GeneratedComInterfaceAttribute özniteliğine sahip bir arabirim tanımlamak desteklenmez.
.NET 9 ve sonraki sürümlerde bu senaryo aşağıdaki kısıtlamalarla desteklenir:
- Temel arabirim türü, türetilen türle aynı hedef çerçeveyi hedefleyecek şekilde derlenmelidir.
- Temel arabirim türü, varsa temel arabiriminin hiçbir üyesini gölgelendirmemelidir.
Ayrıca, başka bir derlemede tanımlanan temel arabirim zincirinde oluşturulan herhangi bir sanal yöntem uzaklığında yapılan değişiklikler, proje yeniden oluşturulana kadar türetilmiş arabirimlerde hesaba bağlanmaz.
Not
.NET 9 ve sonraki sürümlerde, bu özelliği kullanmanın kısıtlamaları ve tuzakları hakkında sizi bilgilendirmek için derleme sınırları boyunca oluşturulan COM arabirimleri devralılırken bir uyarı gönderilir. Sınırlamaları onaylamak ve bütünleştirilmiş kod sınırları boyunca devralmak için bu uyarıyı devre dışı bırakabilirsiniz.
API'leri hazırlama
içindeki Marshal bazı API'ler kaynak tarafından oluşturulan COM ile uyumlu değildir. Bu yöntemleri bir ComWrappers uygulamadaki ilgili yöntemleriyle değiştirin.