Kopyalama ve Sabitleme
Birlikte çalışma yardımcısı, verileri sıralarken kopyalayabilir veya sabitleyebilir. Verilerin kopyalanması, bir bellek konumundaki verilerin bir kopyasını başka bir bellek konumuna yerleştirir. Aşağıdaki çizimde, bir değer türünü kopyalama ile yönetilen bellekten yönetilmeyen belleğe başvuru tarafından geçirilen bir türü kopyalama arasındaki farklar gösterilmektedir.
Değer tarafından geçirilen yöntem bağımsız değişkenleri, yığında değer olarak yönetilmeyen koda göre sıralanır. Kopyalama işlemi doğrudan gerçekleştirilir. Başvuru tarafından geçirilen bağımsız değişkenler yığında işaretçi olarak geçirilir. Başvuru türleri de değere ve başvuruya göre geçirilir. Aşağıdaki çizimde gösterildiği gibi, değer tarafından geçirilen başvuru türleri kopyalanır veya sabitlenir:
Sabitleme işlemi verileri geçerli bellek konumunda geçici olarak kilitleyerek ortak dil çalışma zamanının çöp toplayıcısı tarafından yeniden yerleştirilmesini engeller. Marshaller, kopyalama ek yükünü azaltmak ve performansı artırmak için verileri sabitler. Verilerin türü, hazırlama işlemi sırasında kopyalanıp kopyalanmadığını veya sabitlenip sabitlenmediğini belirler. Sabitleme, gibi nesneler için sıralama sırasında otomatik olarak Stringgerçekleştirilir, ancak sınıfını GCHandle kullanarak belleği el ile de sabitleyebilirsiniz.
Biçimlendirilmiş Blittable Sınıfları
Biçimlendirilmiş blittable sınıfları, hem yönetilen hem de yönetilmeyen bellekte sabit düzen (biçimlendirilmiş) ve ortak veri gösterimine sahiptir. Bu türler sıralama gerektirdiğinde, yığındaki nesneye yönelik bir işaretçi doğrudan çağrıya geçirilir. Çağıran, işaretçi tarafından başvurulmakta olan bellek konumunun içeriğini değiştirebilir.
Not
Parametre Out veya In/Out olarak işaretlenmişse, çağıran bellek içeriğini değiştirebilir. Buna karşılık, parametre biçimlendirilmiş kesilebilir türler için varsayılan olan In olarak ayarlandığında çağıranın içeriği değiştirmekten kaçınması gerekir. In nesnesinin değiştirilmesi, aynı sınıf bir tür kitaplığına aktarıldığında ve daireler arası çağrılar yapmak için kullanıldığında sorun oluşturur.
Biçimlendirilmiş Kesilebilir Olmayan Sınıflar
Biçimlendirilmiş , bölünebilir olmayan sınıfların sabit düzeni (biçimlendirilmiş) vardır, ancak yönetilen ve yönetilmeyen bellekte veri gösterimi farklıdır. Veriler aşağıdaki koşullar altında dönüştürme gerektirebilir:
Bölünebilir olmayan bir sınıf değere göre yapılandırılmışsa, çağıran veri yapısının bir kopyasına yönelik bir işaretçi alır.
Blittable olmayan bir sınıf başvuruya göre yapılandırılmışsa, çağıran veri yapısının bir kopyasına yönelik bir işaretçiyi alır.
InAttribute Öznitelik ayarlanırsa, bu kopya her zaman örneğin durumuyla başlatılır ve gerektiğinde sıralanır.
OutAttribute Öznitelik ayarlanırsa, durum her zaman dönüşte örneğe kopyalanır ve gerektiğinde sıralanır.
Hem InAttribute hem de OutAttribute ayarlanırsa, her iki kopya da gereklidir. Özniteliklerden biri atlanırsa, marshaller iki kopyayı da ortadan kaldırarak iyileştirebilir.
Başvuru Türleri
Başvuru türleri değere veya başvuruya göre geçirilebilir. Değer tarafından geçirildiğinde, yığında türüne yönelik bir işaretçi geçirilir. Başvuru tarafından geçirildiğinde, yığında türüne yönelik bir işaretçi geçirilir.
Başvuru türleri aşağıdaki koşullu davranışa sahiptir:
Bir başvuru türü değere göre geçirilirse ve bölünebilir olmayan türlerin üyelerine sahipse, türler iki kez dönüştürülür:
Yönetilmeyen tarafa bir bağımsız değişken geçirildiğinde.
Aramadan sonra.
Gereksiz yere kopyalanıp dönüştürülmemesi için, bu türler In parametreleri olarak sıralanır. Çağıranın yaptığı değişiklikleri görebilmesi için, çağıranın bağımsız değişkenine InAttribute ve OutAttribute özniteliklerini açıkça uygulamanız gerekir.
Bir başvuru türü değere göre geçirilirse ve yalnızca blittable türlerinin üyelerine sahipse, sıralama sırasında sabitlenebilir ve arayan tarafından türün üyelerinde yapılan değişiklikler çağıran tarafından görülür. Bu davranışı istiyorsanız InAttribute ve OutAttribute'u açıkça uygulayın. Bu yönlü öznitelikler olmadan, birlikte çalışma marshaller yönlü bilgileri tür kitaplığına dışarı aktarmaz (varsayılan olan In olarak dışarı aktarılır) ve bu, COM apartmanlar arası marshalllama ile ilgili sorunlara neden olabilir.
Başvuru türü başvuru tarafından geçirilirse, varsayılan olarak In/Out olarak sıralanır.
System.String ve System.Text.StringBuilder
Veriler değere veya başvuruya göre yönetilmeyen koda sıralandığında, sıralayıcı genellikle verileri ikincil arabelleğe kopyalar (kopyalama sırasında karakter kümelerini dönüştürebilir) ve arabelleğe bir başvuru geçirir. Başvuru SysAllocString ile ayrılmış bir BSTR değilse, başvuru her zaman CoTaskMemAlloc ile ayrılır.
Bir iyileştirme olarak veya StringStringBuilder değere göre (Unicode karakter dizesi gibi) sıralandığında, marshaller çağrıyı yeni bir arabelleğe kopyalamak yerine iç Unicode arabelleğindeki yönetilen dizelere doğrudan bir işaretçi geçirir.
Dikkat
Bir dize değere göre geçirildiğinde, çağıran hiçbir zaman marshaller tarafından geçirilen başvuruyu değiştirmemelidir. Bunu yapmak yönetilen yığını bozabilir.
başvuruya System.String göre geçirildiğinde, marshaller çağrıyı yapmadan önce dizenin içeriğini ikincil arabelleğe kopyalar. Ardından arabelleğin içeriğini çağrıdan döndürülerek yeni bir dizeye kopyalar. Bu teknik sabit yönetilen dizenin değişmeden kalmasını sağlar.
değeri System.Text.StringBuilder geçirildiğinde, marshaller StringBuilder iç arabelleğinin geçici bir kopyasına başvuruyu çağırana geçirir. Arayanın ve çağıranın arabelleğindeki boyutu kabul etmesi gerekir. Çağıran, yeterli uzunlukta bir StringBuilder oluşturmakla sorumludur. Arabelleğin taşmadığından emin olmak için çağıranın gerekli önlemleri alması gerekir. StringBuilder , değer tarafından geçirilen başvuru türlerinin varsayılan olarak parametre olarak In
geçirilmesi kuralı için bir özel durumdur. StringBuilder
her zaman olarak In
/Out
geçirilir.