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 . Oluşturucu, öğesini GeneratedComInterfaceAttributetanı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 ölçüde ortak ve el ile yazılmış güvenli olmayan 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 ve GeneratedComInterfaceAttribute özniteliklerini ekleyinGuidAttribute. Türün işaretlenmesi partial ve oluşturulan koda erişebilmesi için veya görünürlüğüne sahip internalpublic olması gerekir.
[GeneratedComInterface]
[Guid("3faca0d2-e7f1-4e9c-82a6-404fd6e0aab8")]
internal partial interface IFoo
{
void Method(int i);
}
Ardından, COM'a arabirim uygulayan bir sınıfı kullanıma açmak için öğesini uygulayan sınıfa ekleyin GeneratedComClassAttribute . Bu sınıf da ve partial veya internalolmalıdırpublic.
[GeneratedComClass]
internal partial class Foo : IFoo
{
public void Method(int i)
{
// Do things
}
}
Derleme zamanında, oluşturucu ComWrappers API'sinin bir uygulamasını oluşturur ve COM arabirimini kullanmak veya kullanıma açmak için türünü veya özel türetilmiş bir türü kullanabilirsiniz StrategyBasedComWrappers .
[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, parametrelerin sıralamasını MarshalUsingAttribute özelleştirmek için özniteliğine MarshalAsAttribute ve özniteliğin bazı kullanımlarına uyar. Daha fazla bilgi için MarshalUsing parametre hazırlamayı özelleştirme.
GeneratedComInterfaceAttribute.StringMarshalling ve GeneratedComInterfaceAttribute.StringMarshallingCustomType özellikleri tüm parametrelere uygulanır ve diğer sıralama öznitelikleri yoksa arabirimdeki tür string türlerini döndürür.
Ö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# yöntemi imzalarını ve oluşturucunun çıkarımlarını 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 işlemek HRESULT istiyorsanız, oluşturucunun PreserveSigAttribute bu dönüşümü yapmaması gerektiğini belirtmek için yöntemini kullanabilirsiniz. Aşağıdaki kod parçacıkları, oluşturucu uygulandığında [PreserveSig] hangi yerel imzanın beklediğini gösterir. COM yöntemleri döndürmelidir HRESULT, bu nedenle ile PreserveSig herhangi bir yöntemin dönüş değeri olmalıdır int.
[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. dışında bir değere InterfaceTypeAttribute sahip arabirimlerInterfaceIsIUnknown, kaynak tarafından oluşturulan COM'da desteklenmez. olmayan InterfaceTypeAttribute tüm arabirimlerin'den IUnknowntüretilmiş olduğu varsayılır. Bu, varsayılanın InterfaceIsDualolduğu yerleşik COM'dan farklıdır.
Varsayılanları ve desteği hazırlama
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, kesilebilir öğe dizileri de dahil olmak üzere tüm türlerin semantiği vardır[In].[In]ve[Out]özniteliklerine yalnızca dizilerde izin verilir.[Out]Diğer türlerde veya[In, Out]davranışı gerekiyorsa veinparametre değiştiricilerinioutkullanı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 bkz . COM arabirimi devralma ve .NET.
[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);
}
özniteliğine sahip bir arabirimin GeneratedComInterface yalnızca özniteliği olan GeneratedComInterface bir temel arabirimden devralabileceğini unutmayın.
Derleme sınırları boyunca türetilmiş arabirimler
.NET 8'de, başka bir derlemede tanımlanan -attributed arabiriminden türetilen özniteliğine sahip GeneratedComInterfaceAttribute bir GeneratedComInterfacearabirim 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 hedefleyen 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.