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.
COM istemcisi bir .NET nesnesini çağırdığında, ortak dil çalışma zamanı yönetilen nesneyi ve nesne için COM çağrılabilen sarmalayıcıyı (CCW) oluşturur. Bir .NET nesnesine doğrudan başvuru yapılamıyor, COM istemcileri yönetilen nesne için ara sunucu olarak CCW'yi kullanır.
Çalışma zamanı, hizmetlerini isteyen COM istemcilerinin sayısından bağımsız olarak yönetilen bir nesne için tam olarak bir CCW oluşturur. Aşağıdaki çizimde gösterildiği gibi, INew arabirimini sağlayan CCW'ye birden çok COM istemcisi referans tutabilir. CCW ise arabirimi uygulayan ve atık olarak toplanan yönetilen nesneye tek bir başvuru tutar. Hem COM hem de .NET istemcileri aynı yönetilen nesne üzerinde aynı anda istekte bulunabilir.
COM çağrılabilen sarmalayıcılar .NET çalışma zamanı içinde çalışan diğer sınıflar için görünmez. Birincil amaçları, yönetilen ve yönetilmeyen kod arasında çağrıları yönlendirmektir; ancak CCW'ler, sardıkları yönetilen nesnelerin nesne kimliğini ve nesne ömrünü de yönetir.
Nesne Kimliği
Çalışma zamanı, .NET nesnesi için çöp toplanmış yığınından bellek ayırır ve bu, çalışma zamanının nesneyi gerektiğinde bellekte taşımasını sağlar. Buna karşılık, çalışma zamanı, toplama yapılmamış bir heap'ten CCW için bellek ayırarak, COM istemcilerinin doğrudan sarmalayıcıya başvurmasını mümkün hale getirir.
Nesne Ömrü
Sarmalandığı .NET istemcisinin aksine CCW, geleneksel COM biçiminde başvuru olarak sayılır. CCW'deki referans sayısı sıfıra ulaştığında, sarmalayıcı yönetilen nesne üzerindeki referansını bırakır. Bir sonraki çöp toplama döngüsü sırasında, kalan başvuruları olmayan bir yönetilen nesne toplanır.
COM arabirimlerini simüle etme
CCW, COM'un arabirim tabanlı etkileşim zorunluluğu ile tutarlı bir şekilde tüm genel, COM görünür arabirimlerini, veri türlerini ve dönüş değerlerini COM istemcilerine sunar. BIR COM istemcisi için, .NET nesnesindeki yöntemleri çağırma, BIR COM nesnesindeki yöntemleri çağırmayla aynıdır.
CCW, bu sorunsuz yaklaşımı oluşturmak için IUnknown ve IDispatch gibi geleneksel COM arabirimleri üretir. Aşağıdaki çizimde gösterildiği gibi, CCW, sarmaladığı .NET nesnesinde tek bir referans tutar. Hem COM istemcisi hem de .NET nesnesi, CCW'nin proxy ve saplama yapısı aracılığıyla birbirleriyle etkileşim kurar.
.NET çalışma zamanı, yönetilen ortamda bir sınıf tarafından açıkça uygulanan arabirimleri ortaya çıkarmanın yanı sıra, nesnesi adına aşağıdaki tabloda listelenen COM arabirimlerinin uygulamalarını sağlar. Bir .NET sınıfı, bu arabirimlerin kendi uygulamasını sağlayarak varsayılan davranışı geçersiz kılabilir. Ancak, çalışma zamanı her zaman IUnknown ve IDispatch arabirimleri için uygulamayı sağlar.
| Arayüz | Açıklama |
|---|---|
| IDispatch | Türler için geç bağlama mekanizması sağlar. |
| IErrorInfo | Hatanın metinsel açıklamasını, kaynağını, Yardım dosyasını, Yardım bağlamını ve hatayı tanımlayan arabirimin GUID'sini sağlar (.NET sınıfları için her zaman GUID_NULL ). |
| IProvideClassInfo | COM istemcilerinin yönetilen bir sınıf tarafından uygulanan ITypeInfo arabirimine erişim kazanmasını sağlar. COM'dan içeri aktarılmayan türler için COR_E_NOTSUPPORTED, .NET Core'da döner. |
| ISupportErrorInfo | Yönetilen nesnenin IErrorInfo arabirimini destekleyip desteklemediğini saptamak için BIR COM istemcisi etkinleştirir. Öyleyse, istemcinin en son istisna nesnesine yönelik bir işaretçi elde etmesine olanak tanır. Tüm yönetilen türler IErrorInfo arabirimini destekler. |
| ITypeInfo (yalnızca.NET Framework) | Tlbexp.exetarafından üretilen tür bilgileriyle tam olarak aynı olan bir sınıf için tür bilgileri sağlar. |
| IUnknown | COM istemcisinin CCW'nin ömrünü yönetmesini ve tür zorlaması sağlamasını mümkün kılan IUnknown arabiriminin standart uygulamasını sağlar. |
Yönetilen sınıf, aşağıdaki tabloda açıklanan COM arabirimlerini de sağlayabilir.
| Arayüz | Açıklama |
|---|---|
| (_classname) sınıf arabirimi | Çalışma zamanı tarafından kullanıma sunulan ve açıkça tanımlanmayan bir arabirim; yönetilen bir nesnede açıkça kullanıma sunulan tüm genel arabirimleri, yöntemleri, özellikleri ve alanları içerir. |
| IConnectionPoint ve IConnectionPointContainer | Temsilci tabanlı olayları (olay abonelerini kaydetmeye yönelik bir arabirim) kaynak oluşturan nesneler için arabirim. |
| IDispatchEx (yalnızca.NET Framework) | Sınıf IExpando uygularsa çalışma zamanı tarafından sağlanan arabirim. IDispatchEx arabirimi, IDispatch'ın aksine üyelerin numaralandırmasını, toplamasını, silinmesini ve büyük/küçük harfe duyarlı çağrısını etkinleştiren IDispatch arabiriminin bir uzantısıdır. |
| IEnumVARIANT | Sınıf IEnumerable uygularsa koleksiyondaki nesneleri numaralandıran koleksiyon türü sınıfları arabirimi. |
Sınıf arabirimine giriş
Yönetilen kodda açıkça tanımlanmayan sınıf arabirimi, .NET nesnesinde açıkça kullanıma sunulan tüm genel yöntemleri, özellikleri, alanları ve olayları kullanıma sunan bir arabirimdir. Bu arabirim çift amaçlı veya yalnızca dağıtım amaçlı olabilir. Sınıf arabirimi, önünde bir alt çizgi bulunan .NET sınıfının adını alır. Örneğin Memeliler sınıfı için sınıf arabirimi _Mammal.
Türetilmiş sınıflar için, sınıf arabirimi temel sınıfın tüm genel yöntemlerini, özelliklerini ve alanlarını da kullanıma sunar. Türetilmiş sınıf, her temel sınıf için bir sınıf arabirimi de sunar. Örneğin, Memeliler sınıfı, System.Object'i genişleten MammalSuperclass sınıfını genişletiyorsa, .NET nesnesi COM istemcilerine _Mammal, _MammalSuperclass ve _Object adlı üç sınıf arabirimini kullanıma sunar.
Örneğin, aşağıdaki .NET sınıfını göz önünde bulundurun:
' Applies the ClassInterfaceAttribute to set the interface to dual.
<ClassInterface(ClassInterfaceType.AutoDual)> _
' Implicitly extends System.Object.
Public Class Mammal
Sub Eat()
Sub Breathe()
Sub Sleep()
End Class
// Applies the ClassInterfaceAttribute to set the interface to dual.
[ClassInterface(ClassInterfaceType.AutoDual)]
// Implicitly extends System.Object.
public class Mammal
{
public void Eat() {}
public void Breathe() {}
public void Sleep() {}
}
COM istemcisi _Mammal adlı bir sınıf arabirimine işaretçi alabilir. .NET Framework'te, arabirim tanımını içeren bir tür kitaplığı oluşturmak için _Mammal aracını kullanabilirsiniz. Tür Kitaplığı Aktarıcı .NET Core'da desteklenmez. Sınıfı bir Mammal veya daha fazla arabirim uyguladıysa, arabirimler ortak sınıfın altında görünür.
[odl, uuid(…), hidden, dual, nonextensible, oleautomation]
interface _Mammal : IDispatch
{
[id(0x00000000), propget] HRESULT ToString([out, retval] BSTR*
pRetVal);
[id(0x60020001)] HRESULT Equals([in] VARIANT obj, [out, retval]
VARIANT_BOOL* pRetVal);
[id(0x60020002)] HRESULT GetHashCode([out, retval] short* pRetVal);
[id(0x60020003)] HRESULT GetType([out, retval] _Type** pRetVal);
[id(0x6002000d)] HRESULT Eat();
[id(0x6002000e)] HRESULT Breathe();
[id(0x6002000f)] HRESULT Sleep();
}
[uuid(…)]
coclass Mammal
{
[default] interface _Mammal;
}
Sınıf arabirimini oluşturmak isteğe bağlıdır. Varsayılan olarak, COM birlikte çalışma, bir tür kitaplığına dışarı aktardığınız her sınıf için yalnızca dağıtım arabirimi oluşturur. sınıfınıza uygulayarak bu arabirimin otomatik olarak oluşturulmasını ClassInterfaceAttribute engelleyebilir veya değiştirebilirsiniz. Sınıf arabirimi, yönetilen sınıfları COM'a gösterme görevini kolaylaştırsa da, kullanımları sınırlıdır.
Dikkat
Kendi sınıfınızı açıkça tanımlamak yerine sınıf arabirimini kullanmak, yönetilen sınıfınızın gelecekteki sürümünü karmaşık hale getirebilir. Sınıf arabirimini kullanmadan önce lütfen aşağıdaki yönergeleri okuyun.
Sınıf arabirimini oluşturmak yerine COM istemcilerinin kullanması için açık bir arabirim tanımlayın.
COM birlikte çalışma otomatik olarak bir sınıf arabirimi oluşturduğundan, sınıfınızdaki sürüm sonrası değişiklikler ortak dil çalışma zamanı tarafından kullanıma sunulan sınıf arabiriminin düzenini değiştirebilir. COM istemcileri genellikle bir arabirimin düzenindeki değişiklikleri işlemek için hazır olmadığından, sınıfın üye düzenini değiştirirseniz bozulırlar.
Bu kılavuz, COM istemcilerine sunulan arabirimlerin değiştirilemez kalması gerektiğiyle ilgili bir ilkeyi güçlendirir. Arabirim düzenini yanlışlıkla yeniden sıralayarak COM istemcilerini bozma riskini azaltmak için, arabirimleri açıkça tanımlayarak sınıfındaki tüm değişiklikleri arabirim düzeninden yalıtın.
Aşağıdaki kod parçasında gösterildiği gibi sınıf arabiriminin otomatik neslini devre dışı bırakma ve sınıf için açık bir arabirim uygulama için ClassInterfaceAttribute kullanın:
<ClassInterface(ClassInterfaceType.None)>Public Class LoanApp
Implements IExplicit
Sub M() Implements IExplicit.M
…
End Class
[ClassInterface(ClassInterfaceType.None)]
public class LoanApp : IExplicit
{
int IExplicit.M() { return 0; }
}
ClassInterfaceType.None değeri, sınıf meta verileri bir tür kitaplığına aktarıldığında sınıf arabiriminin oluşturulmasını engeller. Yukarıdaki örnekte, COM istemcileri LoanApp sınıfına yalnızca IExplicit arabirimi üzerinden erişebilir.
Gönderme tanımlayıcılarını önbelleğe almaktan kaçının (DispId'ler)
Sınıf arabirimini kullanmak betik tabanlı istemciler, Microsoft Visual Basic 6.0 istemcileri veya arabirim üyelerinin DispId'lerini önbelleğe almayan geç bağlamalı istemciler için uygun bir seçenektir. DispId'ler, geç bağlamayı etkinleştirmek için arabirim üyelerini tanımlar.
Sınıf arabirimi için DispId'lerin oluşturulması, üyenin arabirimdeki konumunu temel alır. Üyenin sırasını değiştirir ve sınıfı bir tür kitaplığına aktarırsanız, sınıf arabiriminde oluşturulan DispId'leri değiştirirsiniz.
Sınıf arabirimini kullanırken geç bağlanan COM istemcilerinin kırılmasını önlemek için ClassInterfaceType.AutoDispatch değeriyle ClassInterfaceAttribute'u uygulayın. Bu değer yalnızca dağıtım yapan sınıf arabirimini uygular, ancak tür kitaplığından arabirim açıklamasını kapsamaz. Arabirim açıklaması olmadan istemciler derleme zamanında DispId'leri önbelleğe alamaz. Bu, sınıf arabirimi için varsayılan arabirim türü olsa da, öznitelik değerini açıkça uygulayabilirsiniz.
<ClassInterface(ClassInterfaceType.AutoDispatch)> Public Class LoanApp
Implements IAnother
Sub M() Implements IAnother.M
…
End Class
[ClassInterface(ClassInterfaceType.AutoDispatch)]
public class LoanApp
{
public int M() { return 0; }
}
Çalışma zamanında bir arabirim üyesinin DispId değerini almak için, COM istemcileri IDispatch.GetIdsOfNames'i çağırabilir. Arabirimde bir yöntemi çağırmak için döndürülen DispId değerini IDispatch.Invoke bağımsız değişkeni olarak geçirin.
Sınıf arabirimi için çift arabirim seçeneğini kullanarak kısıtlayın.
Çift arayüzler, COM istemcileri tarafından arayüz üyelerine erken ve geç bağlamayı etkinleştirir. Tasarım zamanında ve test sırasında sınıf arabirimini ikili olarak ayarlamayı yararlı bulabilirsiniz. Hiçbir zaman değiştirilmeyecek yönetilen bir sınıf (ve temel sınıfları) için bu seçenek de kabul edilebilir. Diğer tüm durumlarda sınıf arabirimini ikili olarak ayarlamaktan kaçının.
Otomatik olarak oluşturulan çift arabirim nadir durumlarda uygun olabilir; ancak daha sık sürümle ilgili karmaşıklık oluşturur. Örneğin, türetilmiş bir sınıfın sınıf arayüzünü kullanan COM istemcileri, temel sınıfta yapılan değişikliklerle kolayca bozulabilir. Bir üçüncü taraf temel sınıfı sağladığında, sınıf arabiriminin düzeni denetiminizin dışındadır. Ayrıca, yalnızca dağıtım arabiriminden farklı olarak, çift arabirim (ClassInterfaceType.AutoDual), dışarı aktarılan tür kitaplığındaki sınıf arabiriminin açıklamasını sağlar. Böyle bir açıklama, geç bağlanan istemcilerin derleme zamanında DispId'leri önbelleğe almalarını teşvik eder.
Tüm COM olay bildirimlerinin geç bağlandığından emin olun.
Varsayılan olarak, COM türü bilgileri doğrudan yönetilen derlemelere eklenir ve bu da birincil birlikte çalışma derlemeleri (PIA) gereksinimini ortadan kaldırır. Ancak, gömülü tür bilgilerinin sınırlamalarından biri, COM olay bildirimlerinin erken bağlı vtable çağrıları tarafından teslimini desteklememesi, ancak yalnızca geç bağlı IDispatch::Invoke çağrıları desteklemesidir.
Uygulamanız COM olay arabirimi yöntemlerine erken bağlanan çağrılar gerektiriyorsa, Visual Studio'daki Birlikte Çalışma Türlerini Ekle özelliğini olarak trueayarlayabilir veya proje dosyanıza aşağıdaki öğeyi ekleyebilirsiniz:
<EmbedInteropTypes>True</EmbedInteropTypes>