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 belirtilir. Dereceye göre belirtilir. İsteğe bağlı olarak sınırlar tarafından belirtilir. type[n,m]
ELEMENT_TYPE_CLASS Bilinmiyor Bilinmiyor Bilinmiyor Array
ELEMENT_TYPE_SZARRAY Türe göre belirtilir. 1 0 type[n]

Yönetilmeyen Diziler

Yönetilmeyen diziler, COM stili güvenli diziler veya sabit veya değişken uzunlukta C stili dizilerdir. Kasa 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
Kasa Array(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 diziler Kasa olarak sıralanamazSZARRAY.
Tür[] <ELEMENT_TYPE_SZARRAY ConvertedType>

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

dizileri Kasa

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, BSTR türlerinin güvenli dizisi yönetilen bir 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 numaralandırmanın SAFEARRAY değerine UnmanagedType 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 oluşturulur. 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ı ELEMENT_TYPE_SZARRAY yerine ELEMENT_TYPE_ARRAY öğe türünü belirtmek üzere değiştirildiğinde yönetilen kodda sıralanabilir. Alternatif olarak, tüm dizileri nesne olarak System.Array içeri aktarmak için /sysarray anahtarını Tlbimp.exe kullanabilirsiniz. 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, lpstr türleri dizisi dize türleri dizisi 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 uzunlukta dizilerle, boyut tür kitaplığından içeri aktarılır ve parametresine 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);

size_is veya length_is özniteliklerini arabirim tanım dili (IDL) kaynağındaki bir diziye uygulayarak boyutu bir istemciye iletebilirsiniz, ancak Microsoft Arabirim Tanım Dili (MIDL) derleyicisi bu bilgileri tür kitaplığına yaymaz. 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 );
    

Sıralayıcı, yönetilmeyen koddan yönetilen koda dizileri sıralarken, dizi boyutunu belirlemek için parametresiyle ilişkili MarshalAsAttribute'u denetler. Dizi boyutu belirtilmezse, yalnızca bir öğe sıraya eklenir.

Not

MarshalAsAttribute'un yönetilen dizileri yönetilmeyen koda sıralama üzerinde hiçbir 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 ücretsiz yöntemleri 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. Kasa Array(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ü><rank>[<bounds]> Unmanagedtype. Kasa Array(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. Kasa Array(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, Dize alanlarının UnmanagedType.BSTR olarak sıralanması gerekir. Aksi takdirde, bir özel durum oluşturulur.

ELEMENT_TYPE_SZARRAY

ELEMENT_TYPE_SZARRAY parametresi (tek boyutlu dizi) içeren bir yöntem .NET derlemesinden tür kitaplığına aktarıldığında, dizi parametresi belirli bir türdeki SAFEARRAY'ye 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, geçirilen yönetilen dizinin boyutuna göre çalışma zamanında 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_TYPE_ARRAY

ELEMENT_TYPE_ARRAY parametresi içeren bir yöntem bir .NET derlemesinden tür kitaplığına aktarıldığında, dizi parametresi belirli bir türdeki SAFEARRAY'ye 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 _Array arabirimine dönüştürülür. Yönetilen dizinin içeriğine yalnızca _Array arabiriminin yöntemleri ve özellikleri aracılığıyla erişilebilir. System.Array, özniteliği kullanılarak MarshalAsAttribute SAFEARRAY olarak da sıralanabilir. 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.Safe array)> ar As System.Array )
void New1( System.Array ar );
void New2( [MarshalAs(UnmanagedType.Safe array)] 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.