Aracılığıyla paylaş


Diziler için Varsayılan Sıralama

Tamamen yönetilen koddan oluşan bir uygulamada, ortak dil çalışma zamanı dizi türlerini In/Out parametreleri olarak geçirir. Buna karşılık, birlikte çalışma sıralayıcısı varsayılan olarak bir diziyi In parametreleri olarak geçirir.

Sabitleme iyileştirmesi ile, bir blittable dizisi aynı apartmandaki nesnelerle etkileşim kurarken Bir In/Out parametresi olarak çalışabilir. Ancak, daha sonra kodu makineler arası ara sunucuyu oluşturmak için kullanılan bir tür kitaplığına aktarırsanız ve bu kitaplık çağrılarınızı daireler arasında sıralamak için kullanılırsa, çağrılar true In parametre davranışına geri dönebilir.

Diziler doğası gereği karmaşıktır ve yönetilen ve yönetilmeyen diziler arasındaki farklar diğer bölünemez türlerden daha fazla bilgi sağlar.

Yönetilen Diziler

Yönetilen dizi türleri farklılık gösterebilir; ancak, System.Array sınıfı tüm dizi türlerinin temel sınıfıdır. System.Array sınıfı, dizilerin derecesini, uzunluğunu ve alt ve üst sınırlarını belirlemenin yanı sıra dizilere erişme, sıralama, arama, kopyalama ve oluşturma yöntemlerine sahiptir.

Bu dizi türleri dinamiktir ve temel sınıf kitaplığında tanımlanmış karşılık gelen bir statik türe sahip değildir. Öğe türünün ve derecelendirmenin her birleşimini ayrı bir dizi türü olarak düşünmek uygundur. Bu nedenle, tek boyutlu bir tamsayı dizisi, tek boyutlu bir çift tür dizisinden farklı türdedir. Benzer şekilde iki boyutlu bir tamsayı dizisi, tek boyutlu bir tamsayı dizisinden farklıdır. Türleri karşılaştırırken dizinin sınırları dikkate alınmaz.

Aşağıdaki tabloda gösterildiği gibi, yönetilen dizinin herhangi bir örneği belirli bir öğe türünde, derecesinde ve alt sınırda olmalıdır.

Yönetilen dizi türü Öğe türü Derece Alt sınır İmza gösterimi
ELEMENT_TYPE_ARRAY Türe göre belirtildi Dereceye göre belirtildi İsteğe bağlı olarak sınırlarla belirtilir type[n,m ]
ELEMENT_TYPE_CLASS Bilinmiyor Bilinmiyor Bilinmiyor System.Array
ELEMENT_TYPE_SZARRAY Türe göre belirtildi 1 0 tür[n]

Yönetilmeyen Diziler

Yönetilmeyen diziler, COM stili güvenli diziler veya sabit veya değişken uzunlukta C stili dizilerdir. Güvenli diziler, ilişkili dizi verilerinin türünü, derecesini ve sınırlarını taşıyan kendi kendini açıklayan dizilerdir. C stili diziler, sabit alt sınırı 0 olan tek boyutlu türlenmiş dizilerdir. Sıralama hizmeti, her iki dizi türü için de sınırlı desteğe sahiptir.

.NET Code'a Dizi Parametreleri Geçirme

Hem C stili diziler hem de güvenli diziler yönetilmeyen koddan .NET koduna güvenli bir dizi veya C stili bir dizi olarak geçirilebilir. Aşağıdaki tabloda yönetilmeyen tür değeri ve içeri aktarılan tür gösterilmektedir.

Yönetilmeyen tür İçeri aktarılan tür
SafeArray(Tür) < ELEMENT_TYPE_SZARRAY ConvertedType>

Derece = 1, alt sınır = 0. Boyut yalnızca yönetilen imzada sağlandığında bilinir. Derece = 1 veya alt sınır = 0 olmayan güvenli diziler SZARRAY olarak sıralanamaz.
Tür[] < ELEMENT_TYPE_SZARRAY ConvertedType>

Derece = 1, alt sınır = 0. Boyut yalnızca yönetilen imzada sağlandığında bilinir.

Güvenli Diziler

Güvenli bir dizi bir tür kitaplığından .NET derlemesine aktarıldığında, dizi bilinen türde (int gibi) tek boyutlu bir diziye dönüştürülür. Parametrelere uygulanan aynı tür dönüştürme kuralları dizi öğeleri için de geçerlidir. Örneğin, güvenli bir tür dizisi BSTR yönetilen dize dizisine, güvenli bir değişken dizisi ise yönetilen bir nesne dizisine dönüşür. SAFEARRAY öğe türü tür kitaplığından yakalanır ve SAFEARRAY numaralandırmanın UnmanagedType değerine kaydedilir.

Güvenli dizinin derecelendirmesi ve sınırları tür kitaplığından belirlenemediğinden, derecenin 1'e eşit olduğu ve alt sınırın 0'a eşit olduğu varsayılır. Derece ve sınırlar, Tür Kitaplığı İçeri Aktarıcısı (Tlbimp.exe) tarafından oluşturulan yönetilen imzada tanımlanmalıdır. Çalışma zamanında yöntemine geçirilen sıralama farklıysa, bir SafeArrayRankMismatchException oluşturulur. Çalışma zamanında geçirilen dizinin türü farklıysa, bir SafeArrayTypeMismatchException atılır. Aşağıdaki örnekte yönetilen ve yönetilmeyen koddaki güvenli diziler gösterilmektedir.

Yönetilmeyen imza

HRESULT New1([in] SAFEARRAY( int ) ar);
HRESULT New2([in] SAFEARRAY( DATE ) ar);
HRESULT New3([in, out] SAFEARRAY( BSTR ) *ar);

Yönetilen imza

Sub New1(<MarshalAs(UnmanagedType.SafeArray, SafeArraySubType:=VT_I4)> _
   ar() As Integer)
Sub New2(<MarshalAs(UnmanagedType.SafeArray, SafeArraySubType:=VT_DATE)> _
   ar() As DateTime)
Sub New3(ByRef <MarshalAs(UnmanagedType.SafeArray, SafeArraySubType:=VT_BSTR)> _
   ar() As String)
void New1([MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VT_I4)] int[] ar) ;
void New2([MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VT_DATE)]
   DateTime[] ar);
void New3([MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VT_BSTR)]
   ref String[] ar);

Çok boyutlu veya sıfıra bağlı olmayan güvenli diziler, Tlbimp.exe tarafından üretilen yöntem imzasının ELEMENT_TYPE_SZARRAY yerine ELEMENT_TYPE_ARRAY öğe türünü belirtmesi amacıyla değiştirilmesi durumunda yönetilen koda sıralanabilir. Alternatif olarak, tüm dizileri nesne olarak içeri aktarmak için /sysarraySystem.Array. Geçirilen dizinin çok boyutlu olduğu bilinen durumlarda, Tlbimp.exe tarafından üretilen ortak ara dil (CIL) kodunu düzenleyebilir ve sonra yeniden derleyebilirsiniz. CIL kodunu değiştirme hakkında ayrıntılı bilgi için bkz . Çalışma Zamanı Çağrılabilen Sarmalayıcıları Özelleştirme.

C Stili Diziler

C stilindeki bir dizi bir tür kitaplığından .NET derlemesine aktarıldığında, dizi ELEMENT_TYPE_SZARRAY dönüştürülür.

Dizi öğesi türü tür kitaplığından belirlenir ve içeri aktarma sırasında korunur. Parametrelere uygulanan dönüştürme kuralları dizi öğeleri için de geçerlidir. Örneğin, bir tür dizisi LPStr bir tür dizisi String haline gelir. Tlbimp.exe dizi öğesi türünü yakalar ve özniteliğini parametresine uygular MarshalAsAttribute .

Dizi sıralamasının 1'e eşit olduğu varsayılır. Derece 1'den büyükse, dizi sütun ana sırasına göre tek boyutlu bir dizi olarak sıralanır. Alt sınır her zaman 0'a eşittir.

Tür kitaplıkları sabit veya değişken uzunlukta diziler içerebilir. Tlbimp.exe tür kitaplıklarında değişken uzunluklu dizileri sıralamak için gereken bilgiler bulunmadığından tür kitaplıklarından yalnızca sabit uzunlukta dizileri içeri aktarabilirsiniz. Sabit uzunluklu dizilerde, boyut tür kitaplığından içeri aktarılır ve parametreye uygulanan MarshalAsAttribute içinde yakalanır.

Aşağıdaki örnekte gösterildiği gibi değişken uzunlukta diziler içeren tür kitaplıklarını el ile tanımlamanız gerekir.

Yönetilmeyen imza

HRESULT New1(int ar[10]);
HRESULT New2(double ar[10][20]);
HRESULT New3(LPWStr ar[10]);

Yönetilen imza

Sub New1(<MarshalAs(UnmanagedType.LPArray, SizeConst=10)> _
   ar() As Integer)
Sub New2(<MarshalAs(UnmanagedType.LPArray, SizeConst=200)> _
   ar() As Double)
Sub New2(<MarshalAs(UnmanagedType.LPArray, _
   ArraySubType=UnmanagedType.LPWStr, SizeConst=10)> _
   ar() As String)
void New1([MarshalAs(UnmanagedType.LPArray, SizeConst=10)] int[] ar);
void New2([MarshalAs(UnmanagedType.LPArray, SizeConst=200)] double[] ar);
void New2([MarshalAs(UnmanagedType.LPArray,
   ArraySubType=UnmanagedType.LPWStr, SizeConst=10)] String[] ar);

Bir diziye boyutunu bir istemciye iletmek üzere size_is veya length_is özniteliklerini Arabirim Tanım Dili (IDL) kaynağında uygulayabilirsiniz, ancak Microsoft Arabirim Tanımlama Dili (MIDL) derleyicisi bu bilgileri tür kitaplığına iletmez. Boyutu bilmeden birlikte çalışma hazırlama hizmeti dizi öğelerini sıralayamaz. Sonuç olarak, değişken uzunluklu diziler başvuru bağımsız değişkenleri olarak içeri aktarılır. Örneğin:

Yönetilmeyen imza

HRESULT New1(int ar[]);
HRESULT New2(int ArSize, [size_is(ArSize)] double ar[]);
HRESULT New3(int ElemCnt, [length_is(ElemCnt)] LPStr ar[]);

Yönetilen imza

Sub New1(ByRef ar As Integer)
Sub New2(ByRef ar As Double)
Sub New3(ByRef ar As String)
void New1(ref int ar);
void New2(ref double ar);
void New3(ref String ar);

Tlbimp.exe tarafından üretilen ortak ara dil (CIL) kodunu düzenleyip yeniden derleyerek, marshaller'a dizi boyutunu sağlayabilirsiniz. CIL kodunu değiştirme hakkında ayrıntılı bilgi için bkz . Çalışma Zamanı Çağrılabilen Sarmalayıcıları Özelleştirme. Dizideki öğelerin sayısını belirtmek için, türü yönetilen yöntem tanımının dizi parametresine aşağıdaki yollardan biriyle uygulayın MarshalAsAttribute :

  • Dizideki öğe sayısını içeren başka bir parametre tanımlayın. Parametreler, ilk parametre 0 olarak başlayarak konuma göre tanımlanır.

    Sub [New](ElemCnt As Integer, _
       <MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=1)> _
       ar() As Integer)
    
    void New(
       int ElemCnt,
       [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] int[] ar );
    
  • Dizinin boyutunu sabit olarak tanımlayın. Örneğin:

    Sub [New](<MarshalAs(UnmanagedType.LPArray, SizeConst:=128)> _
       ar() As Integer)
    
    void New(
       [MarshalAs(UnmanagedType.LPArray, SizeConst=128)] int[] ar );
    

Yönetilmeyen koddan yönetilen koda dizileri yapılandırırken, dizi işleyicisi dizi boyutunu belirlemek için parametresiyle ilişkili MarshalAsAttribute öğesini denetler. Dizi boyutu belirtilmezse, yalnızca bir öğe sıraya eklenir.

Not

MarshalAsAttribute yönetilen dizileri yönetilmeyen koda aktarırken etkisi yoktur. Bu yönde, dizi boyutu inceleme ile belirlenir. Yönetilen dizinin alt kümesini hazırlamanın bir yolu yoktur.

Birlikte çalışma marshaller, bellek ayırmak ve almak için Windows'da CoTaskMemAlloc ve CoTaskMemFree yöntemlerini veya diğer işletim sistemlerinde malloc ve free yöntemlerini kullanır. Yönetilmeyen kod tarafından gerçekleştirilen bellek ayırma da bu yöntemleri kullanmalıdır.

Dizileri COM'a Geçirme

Yönetilen koddan yönetilmeyen koda tüm yönetilen dizi türleri geçirilebilir. Yönetilen türe ve bu türe uygulanan özniteliklere bağlı olarak, aşağıdaki tabloda gösterildiği gibi diziye güvenli bir dizi veya C stili bir dizi olarak erişilebilir.

Yönetilen dizi türü Farklı dışarı aktarıldı
< ELEMENT_TYPE_SZARRAY türü> UnmanagedType öğesini seçin. SafeArray(tür)

UnmanagedType.LPArray

tür, imzada sağlanır. Derece her zaman 1, alt sınır her zaman 0'dır. Boyut her zaman çalışma zamanında bilinir.
< ELEMENT_TYPE_ARRAY tür>< derecelendirmesi>[ < sınırlar ]> UnmanagedType.SafeArray(tür)

UnmanagedType.LPArray

İmzada tür, derece, sınırlar sağlanır. Boyut her zaman çalışma zamanında bilinir.
ELEMENT_TYPE_CLASS <System.Array> UT_Interface

UnmanagedType.SafeArray(tür)

Tür, derece, sınırlar ve boyut her zaman çalışma zamanında bilinir.

OLE Otomasyonu'nda LPSTR veya LPWSTR içeren yapı dizileriyle ilgili bir sınırlama vardır. Bu nedenle alanların StringUnmanagedType.BSTR olarak sıralanması gerekir. Aksi takdirde, bir özel durum oluşturulur.

ELEMENT_TYPE_SZARRAY

Parametre içeren bir ELEMENT_TYPE_SZARRAY yöntem (tek boyutlu dizi) bir .NET derlemesinden tür kitaplığına aktarıldığında, dizi parametresi belirli bir SAFEARRAY türe dönüştürülür. Aynı dönüştürme kuralları dizi öğesi türleri için de geçerlidir. Yönetilen dizinin içeriği, yönetilen bellekten SAFEARRAY'ye otomatik olarak kopyalanır. Örneğin:

Yönetilen imza

Sub [New](ar() As Long)
Sub [New](ar() As String)
void New(long[] ar );
void New(String[] ar );

Yönetilmeyen imza

HRESULT New([in] SAFEARRAY( long ) ar);
HRESULT New([in] SAFEARRAY( BSTR ) ar);

Güvenli dizilerin sırası her zaman 1, alt sınır ise her zaman 0'dır. Boyut, çalışma zamanında geçirilen yönetilen dizinin boyutuna göre belirlenir.

Dizi, özniteliği kullanılarak MarshalAsAttribute C stili bir dizi olarak da sıralanabilir. Örneğin:

Yönetilen imza

Sub [New](<MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=1)> _
   ar() As Long, size as Integer)
Sub [New](<MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=1)> _
   ar() As String, size as Integer)
Sub [New](<MarshalAs(UnmanagedType.LPArray, _
   ArraySubType= UnmanagedType.LPStr, SizeParamIndex:=1)> _
   ar() As String, size as Integer)
void New([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]
   long [] ar, int size );
void New([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]
   String [] ar, int size );
void New([MarshalAs(UnmanagedType.LPArray, ArraySubType=
   UnmanagedType.LPStr, SizeParamIndex=1)]
   String [] ar, int size );

Yönetilmeyen imza

HRESULT New(long ar[]);
HRESULT New(BSTR ar[]);
HRESULT New(LPStr ar[]);

Sıralayıcı diziyi sıralamak için gereken uzunluk bilgilerine sahip olsa da, dizi uzunluğu genellikle çağırana uzunluğu iletmek için ayrı bir bağımsız değişken olarak geçirilir.

Element_Türü_Dizisi

Parametre içeren bir ELEMENT_TYPE_ARRAY yöntem bir .NET derlemesinden tür kitaplığına aktarıldığında, dizi parametresi belirli bir SAFEARRAY türe dönüştürülür. Yönetilen dizinin içeriği, yönetilen bellekten SAFEARRAY'ye otomatik olarak kopyalanır. Örneğin:

Yönetilen imza

Sub [New](ar(,) As Long)
Sub [New](ar(,) As String)
void New( long [,] ar );
void New( String [,] ar );

Yönetilmeyen imza

HRESULT New([in] SAFEARRAY( long ) ar);
HRESULT New([in] SAFEARRAY( BSTR ) ar);

Güvenli dizilerin derecelendirmesi, boyutu ve sınırları, yönetilen dizinin özellikleri tarafından çalışma zamanında belirlenir.

Dizi, özniteliği uygulanarak MarshalAsAttribute C stili bir dizi olarak da sıralanabilir. Örneğin:

Yönetilen imza

Sub [New](<MarshalAs(UnmanagedType.LPARRAY, SizeParamIndex:=1)> _
   ar(,) As Long, size As Integer)
Sub [New](<MarshalAs(UnmanagedType.LPARRAY, _
   ArraySubType:=UnmanagedType.LPStr, SizeParamIndex:=1)> _
   ar(,) As String, size As Integer)
void New([MarshalAs(UnmanagedType.LPARRAY, SizeParamIndex=1)]
   long [,] ar, int size );
void New([MarshalAs(UnmanagedType.LPARRAY,
   ArraySubType= UnmanagedType.LPStr, SizeParamIndex=1)]
   String [,] ar, int size );

Yönetilmeyen imza

HRESULT New(long ar[]);
HRESULT New(LPStr ar[]);

İç içe diziler sıraya alınamaz. Örneğin, aşağıdaki imza Tür Kitaplığı Verme (Tlbexp.exe) ile dışarı aktarıldığında bir hata oluşturur.

Yönetilen imza

Sub [New](ar()()() As Long)
void New(long [][][] ar );

<System.Array ELEMENT_TYPE_CLASS>

Parametre içeren bir System.Array yöntem bir .NET derlemesinden tür kitaplığına aktarıldığında, dizi parametresi bir _Array arabirime dönüştürülür. Yönetilen dizinin içeriğine yalnızca arabiriminin yöntemleri ve özellikleri _Array aracılığıyla erişilebilir. System.Array da SAFEARRAY özniteliği kullanılarak bir MarshalAsAttribute olarak marşhalledilebilir. Güvenli bir dizi olarak sıralandığında, dizi öğeleri değişken olarak sıralanır. Örneğin:

Yönetilen imza

Sub New1( ar As System.Array )
Sub New2( <MarshalAs(UnmanagedType.SafeArray)> ar As System.Array )
void New1( System.Array ar );
void New2( [MarshalAs(UnmanagedType.SafeArray)] System.Array ar );

Yönetilmeyen imza

HRESULT New([in] _Array *ar);
HRESULT New([in] SAFEARRAY(VARIANT) ar);

Yapılar İçinde Diziler

Yönetilmeyen yapılar katıştırılmış diziler içerebilir. Varsayılan olarak, bu eklenmiş dizi alanları SAFEARRAY olarak sıralanır. Aşağıdaki örnekte, s1 doğrudan yapının içinde ayrılan ekli bir dizidir.

Yönetilmeyen gösterim

struct MyStruct {
    short s1[128];
}

Diziler olarak UnmanagedTypesıralanabilir ve bu da alanı ayarlamanızı MarshalAsAttribute gerektirir. Boyut yalnızca sabit olarak ayarlanabilir. Aşağıdaki kod, ilgili yönetilen tanımını MyStructgösterir.

Public Structure <StructLayout(LayoutKind.Sequential)> MyStruct
   Public <MarshalAs(UnmanagedType.ByValArray, SizeConst := 128)> _
     s1() As Short
End Structure
[StructLayout(LayoutKind.Sequential)]
public struct MyStruct {
   [MarshalAs(UnmanagedType.ByValArray, SizeConst=128)] public short[] s1;
}

Ayrıca bkz.