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.
olarak System.Object yazılan parametreler ve alanlar, yönetilmeyen koda aşağıdaki türlerden biri olarak gösterilebilir:
Nesne bir parametre olduğunda bir değişken.
Nesne bir yapı alanı olduğunda arabirim.
Yalnızca COM birlikte çalışma, nesne türleri için sıralamayı destekler. Varsayılan davranış, nesneleri COM varyantlarına göre sıralamaktır. Bu kurallar yalnızca tür Object için geçerlidir ve Object sınıfından türetilen kesin tür belirlenmiş nesnelere uygulanmaz.
Marshalling Seçenekleri
Aşağıdaki tabloda Object veri türü için sıralama seçenekleri gösterilmektedir.
MarshalAsAttribute özniteliği, nesneleri sıralamak için birkaç UnmanagedType numaralandırma değeri sağlar.
| Numaralandırma türü | Yönetilmeyen biçimin açıklaması |
|---|---|
|
YönetilmeyenTür.Yapı (parametreler için varsayılan) |
COM stili bir değişken. |
| UnmanagedType.Interface | Mümkünse IDispatch bir arabirim; değilse bir IUnknown arabirim. |
|
YönetimsizTür.IUnknown (alanlar için varsayılan) |
Bir IUnknown arabirim. |
| UnmanagedType.IDispatch | Bir IDispatch arabirim. |
Aşağıdaki örnekte için MarshalObjectyönetilen arabirim tanımı gösterilmektedir.
Interface MarshalObject
Sub SetVariant(o As Object)
Sub SetVariantRef(ByRef o As Object)
Function GetVariant() As Object
Sub SetIDispatch( <MarshalAs(UnmanagedType.IDispatch)> o As Object)
Sub SetIDispatchRef(ByRef <MarshalAs(UnmanagedType.IDispatch)> o _
As Object)
Function GetIDispatch() As <MarshalAs(UnmanagedType.IDispatch)> Object
Sub SetIUnknown( <MarshalAs(UnmanagedType.IUnknown)> o As Object)
Sub SetIUnknownRef(ByRef <MarshalAs(UnmanagedType.IUnknown)> o _
As Object)
Function GetIUnknown() As <MarshalAs(UnmanagedType.IUnknown)> Object
End Interface
interface MarshalObject {
void SetVariant(Object o);
void SetVariantRef(ref Object o);
Object GetVariant();
void SetIDispatch ([MarshalAs(UnmanagedType.IDispatch)]Object o);
void SetIDispatchRef([MarshalAs(UnmanagedType.IDispatch)]ref Object o);
[MarshalAs(UnmanagedType.IDispatch)] Object GetIDispatch();
void SetIUnknown ([MarshalAs(UnmanagedType.IUnknown)]Object o);
void SetIUnknownRef([MarshalAs(UnmanagedType.IUnknown)]ref Object o);
[MarshalAs(UnmanagedType.IUnknown)] Object GetIUnknown();
}
Aşağıdaki kod MarshalObject arabirimini bir tür kitaplığına dışa aktarır.
interface MarshalObject {
HRESULT SetVariant([in] VARIANT o);
HRESULT SetVariantRef([in,out] VARIANT *o);
HRESULT GetVariant([out,retval] VARIANT *o)
HRESULT SetIDispatch([in] IDispatch *o);
HRESULT SetIDispatchRef([in,out] IDispatch **o);
HRESULT GetIDispatch([out,retval] IDispatch **o)
HRESULT SetIUnknown([in] IUnknown *o);
HRESULT SetIUnknownRef([in,out] IUnknown **o);
HRESULT GetIUnknown([out,retval] IUnknown **o)
}
Not
Interop marshaller, çağrıdan sonra değişken içinde ayrılan nesneleri otomatik olarak serbest bırakır.
Aşağıdaki örnekte biçimlendirilmiş bir değer türü gösterilmektedir.
Public Structure ObjectHolder
Dim o1 As Object
<MarshalAs(UnmanagedType.IDispatch)> Public o2 As Object
End Structure
public struct ObjectHolder {
Object o1;
[MarshalAs(UnmanagedType.IDispatch)]public Object o2;
}
Aşağıdaki kod, biçimlendirilmiş türü bir tür kitaplığına dışarı aktarır.
struct ObjectHolder {
VARIANT o1;
IDispatch *o2;
}
Nesneyi Arabirime Yerleştirme
Bir nesne COM'a arabirim olarak sunulduğunda, bu arabirim yönetilen türün Object ( _Object arabirim) sınıf arabirimidir. Bu arabirim, elde edilen tür kitaplığında IDispatch (UnmanagedType) veya IUnknown olarak UnmanagedType.IUnknown şeklinde türlendirilir. COM istemcileri, yönetilen sınıfın üyelerini veya türetilmiş sınıflarının _Object arabirimi aracılığıyla uygulanan üyelerini dinamik olarak çağırabilir. İstemci, yönetilen tür tarafından açıkça uygulanan diğer arabirimleri edinmek için QueryInterface öğesini de çağırabilir.
Nesneyi Çeşitlendirmeye Göre Sıralama
Bir nesne bir değişkene göre yapılandırıldığında, iç değişken türü çalışma zamanında aşağıdaki kurallara göre belirlenir:
Nesne başvurusu null (Visual Basic'te Nothing) ise, nesne VT_EMPTY türünde bir değişkene dönüştürülür.
Nesne aşağıdaki tabloda listelenen herhangi bir türün örneğiyse, sonuçta elde edilen değişken türü, marshaller'da yerleşik olarak bulunan kurallar tarafından belirlenir ve tabloda gösterilir.
Sıralama davranışını açıkça denetlemesi gereken diğer nesneler arabirimi uygulayabilir IConvertible . Bu durumda, variant türü, IConvertible.GetTypeCode yönteminin döndürdüğü tür koduyla belirlenir. Aksi takdirde, nesne VT_UNKNOWN türünde bir değişken olarak yönlendirilir.
Sistem Türlerini Varyanta Dönüştürme
Aşağıdaki tabloda yönetilen nesne türleri ve buna karşılık gelen COM değişken türleri gösterilmektedir. Bu türler yalnızca çağrılan yöntemin imzası türünde System.Objectolduğunda dönüştürülür.
| Nesne türü | COM değişken türü |
|---|---|
| Null nesne başvurusu (Nothing in Visual Basic). | VT_EMPTY |
| System.DBNull | VT_NULL |
| System.Runtime.InteropServices.ErrorWrapper | VT_ERROR |
| System.Reflection.Missing | VT_ERROR ile E_PARAMNOTFOUND |
| System.Runtime.InteropServices.DispatchWrapper | VT_DISPATCH |
| System.Runtime.InteropServices.UnknownWrapper | VT_UNKNOWN |
| System.Runtime.InteropServices.CurrencyWrapper | VT_CY |
| System.Boolean | VT_BOOL |
| System.SByte | VT_I1 |
| System.Byte | VT_UI1 |
| System.Int16 | VT_I2 |
| System.UInt16 | VT_UI2 |
| System.Int32 | VT_I4 |
| System.UInt32 | VT_UI4 |
| System.Int64 | VT_I8 |
| System.UInt64 | VT_UI8 |
| System.Single | VT_R4 |
| System.Double | VT_R8 |
| System.Decimal | VT_DECIMAL |
| System.DateTime | VT_DATE |
| System.String | VT_BSTR |
| System.IntPtr | VT_INT |
| System.UIntPtr | VT_UINT |
| System.Array | VT_ARRAY |
MarshalObject Aşağıdaki kod örneği, önceki örnekte tanımlanan arabirimi kullanarak çeşitli çeşitleme türlerinin COM sunucusuna nasıl geçir yapılacağını gösterir.
Dim mo As New MarshalObject()
mo.SetVariant(Nothing) ' Marshal as variant of type VT_EMPTY.
mo.SetVariant(System.DBNull.Value) ' Marshal as variant of type VT_NULL.
mo.SetVariant(CInt(27)) ' Marshal as variant of type VT_I2.
mo.SetVariant(CLng(27)) ' Marshal as variant of type VT_I4.
mo.SetVariant(CSng(27.0)) ' Marshal as variant of type VT_R4.
mo.SetVariant(CDbl(27.0)) ' Marshal as variant of type VT_R8.
MarshalObject mo = new MarshalObject();
mo.SetVariant(null); // Marshal as variant of type VT_EMPTY.
mo.SetVariant(System.DBNull.Value); // Marshal as variant of type VT_NULL.
mo.SetVariant((int)27); // Marshal as variant of type VT_I2.
mo.SetVariant((long)27); // Marshal as variant of type VT_I4.
mo.SetVariant((single)27.0); // Marshal as variant of type VT_R4.
mo.SetVariant((double)27.0); // Marshal as variant of type VT_R8.
karşılık gelen yönetilen türleri olmayan COM türleri, , ErrorWrapper, DispatchWrapperve UnknownWrappergibi CurrencyWrappersarmalayıcı sınıfları kullanılarak sıralanabilir. Aşağıdaki kod örneğinde, com sunucusuna çeşitli türlerde çeşitlemeler geçirmek için bu sarmalayıcıların nasıl kullanılacağı gösterilmektedir.
Imports System.Runtime.InteropServices
' Pass inew as a variant of type VT_UNKNOWN interface.
mo.SetVariant(New UnknownWrapper(inew))
' Pass inew as a variant of type VT_DISPATCH interface.
mo.SetVariant(New DispatchWrapper(inew))
' Pass a value as a variant of type VT_ERROR interface.
mo.SetVariant(New ErrorWrapper(&H80054002))
' Pass a value as a variant of type VT_CURRENCY interface.
mo.SetVariant(New CurrencyWrapper(New Decimal(5.25)))
using System.Runtime.InteropServices;
// Pass inew as a variant of type VT_UNKNOWN interface.
mo.SetVariant(new UnknownWrapper(inew));
// Pass inew as a variant of type VT_DISPATCH interface.
mo.SetVariant(new DispatchWrapper(inew));
// Pass a value as a variant of type VT_ERROR interface.
mo.SetVariant(new ErrorWrapper(0x80054002));
// Pass a value as a variant of type VT_CURRENCY interface.
mo.SetVariant(new CurrencyWrapper(new Decimal(5.25)));
Sarmalayıcı sınıfları ad alanında System.Runtime.InteropServices tanımlanır.
IConvertible Arabirimini Variant'e Dönüştürme
Önceki bölümde listelenenler dışındaki türler, IConvertible arabirimini uygulayarak bunların nasıl yönlendirileceğini denetleyebilir. Eğer nesne IConvertible arabirimini uyguluyorsa, COM değişken türü, TypeCode yönteminden döndürülen IConvertible.GetTypeCode sabit listesi değeri tarafından çalışma zamanında belirlenir.
Aşağıdaki tabloda numaralandırma için TypeCode olası değerler ve her değer için karşılık gelen COM değişken türü gösterilmektedir.
| TypeCode | COM değişken türü |
|---|---|
| TypeCode.Empty | VT_EMPTY |
| TypeCode.Object | VT_UNKNOWN |
| TypeCode.DBNull | VT_NULL |
| TypeCode.Boolean | VT_BOOL |
| TypeCode.Char | VT_UI2 |
| TypeCode.Sbyte | VT_I1 |
| TypeCode.Byte | VT_UI1 |
| TypeCode.Int16 | VT_I2 |
| TypeCode.UInt16 | VT_UI2 |
| TypeCode.Int32 | VT_I4 |
| TypeCode.UInt32 | VT_UI4 |
| TypeCode.Int64 | VT_I8 |
| TypeCode.UInt64 | VT_UI8 |
| TypeCode.Single | VT_R4 |
| TypeCode.Double | VT_R8 |
| TypeCode.Decimal | VT_DECIMAL |
| TypeCode.DateTime | VT_DATE |
| TypeCode.String | VT_BSTR |
| Desteklenmiyor. | VT_INT |
| Desteklenmiyor. | VT_UINT |
| Desteklenmiyor. | VT_ARRAY |
| Desteklenmiyor. | VT_RECORD |
| Desteklenmiyor. | VT_CY |
| Desteklenmiyor. | VT_VARIANT |
COM değişkeninin değeri , IConvertible.ToTürü arabirimi çağrılarak belirlenir; burada ToTür , IConvertible.GetTypeCode'dan döndürülen türe karşılık gelen dönüştürme yordamıdır. Örneğin, IConvertible.GetTypeCode'dan TypeCode.Double döndüren bir nesne, VT_R8 türünde bir COM değişkeni olarak sıralanır. COM değişkeninin dblVal alanında depolanan değişken değerini elde etmek için IConvertible arabirimine dönüştürme yaparak ve ardından ToDouble yöntemini çağırarak kullanabilirsiniz.
Varyantın Nesneye Dönüştürülmesi
Bir varyantı bir nesneye sıralarken, sıralanmış değişkenin türü ve bazen değeri, üretilen nesnenin türünü belirler. Aşağıdaki tabloda, com'dan .NET Framework'e bir değişken geçirildiğinde m marshallerreates tarafından belirlenen her değişken türü ve ilgili nesne türü tanımlanmaktadır.
| COM değişken türü | Nesne türü |
|---|---|
| VT_EMPTY | Null nesne başvurusu (Visual Basic'te Nothing). |
| VT_NULL | System.DBNull |
| VT_DISPATCH | System.__ComObject veya (pdispVal == null ise) null |
| VT_UNKNOWN | System.__ComObject veya null eğer (punkVal == null) |
| VT_ERROR | System.UInt32 |
| VT_BOOL | System.Boolean |
| VT_I1 | System.SByte |
| VT_UI1 | System.Byte |
| VT_I2 | System.Int16 |
| VT_UI2 | System.UInt16 |
| VT_I4 | System.Int32 |
| VT_UI4 | System.UInt32 |
| VT_I8 | System.Int64 |
| VT_UI8 | System.UInt64 |
| VT_R4 | System.Single |
| VT_R8 | System.Double |
| VT_DECIMAL | System.Decimal |
| VT_DATE | System.DateTime |
| VT_BSTR | System.String |
| VT_INT | System.Int32 |
| VT_UINT | System.UInt32 |
| VT_ARRAY | VT_* | System.Array |
| VT_CY | System.Decimal |
| VT_RECORD | Karşılık gelen kutulanmış değer türü. |
| VT_VARIANT | Desteklenmiyor. |
COM'dan yönetilen koda ve ardından COM'a geri geçirilen değişken türleri, çağrı süresi boyunca aynı değişken türünü koruyamayabilir. COM'dan .NET Framework'e VT_DISPATCH türde bir değişken geçirildiğinde ne olacağını göz önünde bulundurun. Sıralama sırasında, değişken bir System.Object öğesine dönüştürülür.
Object daha sonra COM'a geri geçirilirse, VT_UNKNOWN türündeki bir değişkene geri döner. Bir nesne yönetilen koddan COM'a sıralandığında üretilen değişkenin ilk olarak nesneyi üretmek için kullanılan değişkenle aynı türde olacağının garantisi yoktur.
ByRef Değişkenlerini Yönlendirme
Değişkenlerin kendileri değere veya başvuru yoluyla geçirilebilse de, VT_BYREF bayrağı, değişkenin içeriğinin değer yerine başvuru yoluyla geçirildiğini belirtmek için herhangi bir değişken türüyle de kullanılabilir. Başvuruya göre varyantları sıralama ve bayrak kümesiyle VT_BYREF bir değişken hazırlama arasındaki fark kafa karıştırıcı olabilir. Aşağıdaki çizimde farklar açıklanır:
Değer ve referans ile geçirilen varyantlar
Nesneleri ve değişkenleri değere göre sıralamak için varsayılan davranış
Nesneleri yönetilen koddan COM'a geçirirken, nesnenin içeriği, Marshalling Object to Variant içinde tanımlanan kurallar kullanılarak, marshaller tarafından oluşturulan yeni bir değişkene kopyalanır. Yönetilmeyen taraftaki varyant üzerinde yapılan değişiklikler, çağrıdan döndüğünde özgün nesneye geri yayılmaz.
tr-TR: Varyantları COM'dan yönetilen koda geçirirken, varyantın içeriği yeni oluşturulan bir nesneye kopyalanır ve Varyantın Nesneye Dönüştürülmesi'nde tanımlı kurallar kullanılarak yapılır. Yönetilen taraftaki nesne üzerinde yapılan değişiklikler, çağrı dönüşü sırasında özgün varyanta geri iletilmez.
Başvuruya göre nesneleri ve değişkenleri sıralamak için varsayılan davranış
Değişiklikleri çağırana geri yaymak için parametrelerin başvuru yoluyla iletilmesi gerekir. Örneğin, C# dilinde ref (veya Visual Basic yönetilen kodunda ByRef) anahtar sözcüğünü kullanarak parametreleri referans ile geçirebilirsiniz. COM'da başvuru parametreleri variant * gibi bir işaretçi kullanılarak geçirilir.
Bir nesneyi başvuruya göre COM'a geçirirken, marshaller yeni bir değişken oluşturur ve çağrı yapılmadan önce nesne başvurusunun içeriğini değişkene kopyalar. Değişken, kullanıcının değişkenin içeriğini değiştirmekte serbest olduğu yönetilmeyen işleve geçirilir. Çağrı tamamlandıktan sonra, yönetilmeyen tarafındaki varyantta yapılan tüm değişiklikler orijinal nesneye yayılır. Değişkenin türü çağrıya geçirilen değişkenin türünden farklıysa, değişiklikler farklı türde bir nesneye geri yayılır. Yani, çağrıya geçirilen nesnenin türü, çağrıdan döndürülen nesnenin türünden farklı olabilir.
Referansla yönetilen koda bir varyant geçirirken, marshaller yeni bir nesne oluşturur ve çağrıyı gerçekleştirmeden önce varyantın içeriğini nesneye kopyalar. Nesneye başvuru yönetilen işleve geçirilir ve burada kullanıcı nesneyi değiştirebilir. Çağrıdan dönüşte, referans alınan nesnede yapılan tüm değişiklikler özgün varyanta geri aktarılır. Nesnenin türü çağrıya geçirilen nesnenin türünden farklıysa, özgün değişkenin türü değiştirilir ve değer değişkene geri yayılır. Yine, çağrıya geçirilen değişkenin türü, çağrıdan döndürülen değişkenin türünden farklı olabilir.
VT_BYREF bayrağı ayarlanmış bir değişken için varsayılan sıralama davranışı
Yönetilen koda değere göre geçirilen bir değişkenin, değer yerine başvuru içerdiğini belirtmek için
VT_BYREFbayrağı ayarlanabilir. Bu durumda, değişken değere göre geçirildiği için değişken yine de bir nesneye göre sıraya alınır. Marshaller, variant içeriğini otomatik olarak dereferans eder ve çağrı başlatılmadan önce yeni oluşturulmuş bir nesneye kopyalar. Nesne daha sonra yönetilen işleve geçirilir; ancak, çağrıdan dönüldüğünde, nesne orijinal değişkene geri yansıtılmaz. Yönetilen nesnede yapılan değişiklikler kaybolur.Dikkat
Değişkende
VT_BYREFbayrağı ayarlanmış olsa bile, değer tarafından geçirilen bir değişkenin değerini değiştirmenin hiçbir yolu yoktur.Yönetilen koda başvuruyla geçirilen bir değişken, başka bir referans içerdiğini belirtmek için
VT_BYREFbayrağı da ayarlanabilir. Eğer öyleyse, değişken başvuru ile geçirildiği için, birrefnesneye dönüştürülür. Marshaller, değişkenin içeriğine otomatik olarak doğrudan erişir ve çağrıyı yapmadan önce bu içeriği yeni oluşturulan bir nesneye kopyalar. Çağrıdan dönen nesnenin değeri, yalnızca nesnenin geçirilen nesneyle aynı türde olduğu takdirde, orijinal varyant içindeki başvuruya geri aktarılır. Yani yayılım, bayrağı ayarlanmışVT_BYREFbir değişkenin türünü değiştirmez. Nesnenin türü çağrı sırasında değiştirilirse, çağrıdan dönüşte bir InvalidCastException oluşur.
Aşağıdaki tabloda, çeşitlemeler ve nesneler için yayma kuralları özetlemektedir.
| Kaynak | Amaç | Geriye yayılan değişiklikler |
|---|---|---|
| Değişkenv | Nesneo | Asla |
| Nesneo | Değişkenv | Asla |
| Değişken*pv | Başvuru Nesnesio | Her zaman |
| Referans nesnesio | Değişken*fv | Her zaman |
| Değişkenv(VT_BYREF|VT_*) | Nesneo | Asla |
| Değişkenv(VT_BYREF|VT_) | Başvuru Nesnesio | Yalnızca tür değişmediyse. |