ICustomMarshaler Arabirim
Tanım
Önemli
Bazı bilgiler ürünün ön sürümüyle ilgilidir ve sürüm öncesinde önemli değişiklikler yapılmış olabilir. Burada verilen bilgilerle ilgili olarak Microsoft açık veya zımni hiçbir garanti vermez.
Yöntem çağrılarını işlemek için özel sarmalayıcılar sağlar.
public interface class ICustomMarshaler
public interface ICustomMarshaler
[System.Runtime.InteropServices.ComVisible(true)]
public interface ICustomMarshaler
type ICustomMarshaler = interface
[<System.Runtime.InteropServices.ComVisible(true)>]
type ICustomMarshaler = interface
Public Interface ICustomMarshaler
- Türetilmiş
- Öznitelikler
Açıklamalar
ICustomMarshaler Arabirimi, yöntem çağrılarını işlemek için özel sarmalayıcılar sunar.
Bir marshaller, eski ve yeni arabirimlerin işlevselliği arasında bir köprü sağlar. Özel hazırlama aşağıdaki avantajları sağlar:
- Eski bir arabirimle çalışacak şekilde tasarlanmış istemci uygulamalarının yeni bir arabirim uygulayan sunucularla da çalışmasını sağlar.
- Yeni bir arabirimle çalışacak şekilde derlenen istemci uygulamalarının eski bir arabirim uygulayan sunucularla çalışmasını sağlar.
Farklı marşaling davranışı tanıtan veya Bileşen Nesne Modeli'ne (COM) farklı bir şekilde kullanıma sunulan bir arabiriminiz varsa, interop marshaller yerine özel bir marshaller tasarlayabilirsiniz. Özel bir marshaller kullanarak yeni .NET bileşenleriyle mevcut COM bileşenleri arasındaki farkı en aza indirebilirsiniz.
Örneğin, adlı INewbir yönetilen arabirim geliştirdiğinizi varsayalım. Bu arabirim, standart bir COM çağrılabilen sarmalayıcı (CCW) aracılığıyla COM'a sunulduğunda, yönetilen arabirimle aynı yöntemlere sahiptir ve birlikte çalışma marshaller'ını oluşturan sıralama kurallarını kullanır. Şimdi, IOld adlı iyi bilinen bir COM arabiriminin, INew arabirimi ile aynı işlevselliği sağladığını varsayalım. Özel bir marshaller tasarlayarak, yalnızca çağrıları IOld arabiriminin yönetilen uygulamasına delege eden yönetilmeyen bir INew uygulaması sağlayabilirsiniz. Bu nedenle, özel marshaller yönetilen ve yönetilmeyen arabirimler arasında bir köprü işlevi görür.
Note
Yönetilen koddan sadece dağıtım yapılan bir arabirimdeki yönetilmeyen koda çağrı yapılırken özel marshaller'lar çağrılmaz.
Dizileme türünü tanımla
Özel bir marshaller oluşturabilmeniz için önce, sıralanacak yönetilen ve yönetilmeyen arabirimleri tanımlamanız gerekir. Bu arabirimler genellikle aynı işlevi gerçekleştirir ancak yönetilen ve yönetilmeyen nesnelere farklı şekilde sunulur.
Yönetilen derleyici meta verilerden yönetilen bir arabirim oluşturur ve sonuçta elde edilen arabirim diğer yönetilen arabirimlere benzer. Aşağıdaki örnekte tipik bir arabirim gösterilmektedir.
public interface INew
{
void NewMethod();
}
Public Interface INew
Sub NewMethod()
End Interface
Yönetilmeyen türü Arabirim Tanım Dili'nde (IDL) tanımlar ve Microsoft Arabirim Tanım Dili (MIDL) derleyicisi ile derlersiniz. Aşağıdaki örnekte gösterildiği gibi, bir kitaplık deyimi içinde arabirimi tanımlar ve evrensel benzersiz tanımlayıcı (UUID) özniteliğine sahip bir arabirim kimliği atarsınız.
[uuid(9B2BAADA-0705-11D3-A0CD-00C04FA35826)]
library OldLib {
[uuid(9B2BAADD-0705-11D3-A0CD-00C04FA35826)]
interface IOld : IUnknown
HRESULT OldMethod();
}
MIDL derleyicisi birkaç çıkış dosyası oluşturur. Arabirim Old.idl içinde tanımlanmışsa, Old_i.c çıkış dosyası aşağıdaki örnekte gösterildiği gibi arabirimin arabirim tanımlayıcısı (IID) ile bir const değişken tanımlar.
const IID IID_IOld = {0x9B2BAADD,0x0705,0x11D3,{0xA0,0xCD,0x00,0xC0,0x4F,0xA3,0x58,0x26}};
Old.h dosyası da MIDL tarafından oluşturulur. C++ kaynak kodunuza dahil edilebilecek arabirimin C++ tanımını içerir.
ICustomMarshaler arabirimini uygulama
Çalışma zamanına uygun sarmalayıcıları sağlamak için özel marshaller'ınız ICustomMarshaler arabirimini uygulamalıdır.
Aşağıdaki C# kodu, tüm özel marshallers tarafından uygulanması gereken temel arabirimi görüntüler.
public interface ICustomMarshaler
{
Object MarshalNativeToManaged(IntPtr pNativeData);
IntPtr MarshalManagedToNative(Object ManagedObj);
void CleanUpNativeData(IntPtr pNativeData);
void CleanUpManagedData(Object ManagedObj);
int GetNativeDataSize();
}
Public Interface ICustomMarshaler
Function MarshalNativeToManaged( pNativeData As IntPtr ) As Object
Function MarshalManagedToNative( ManagedObj As Object ) As IntPtr
Sub CleanUpNativeData( pNativeData As IntPtr )
Sub CleanUpManagedData( ManagedObj As Object )
Function GetNativeDataSize() As Integer
End Interface
Arayüz, ICustomMarshaler dönüştürme desteği, temizleme desteği ve taşınacak veriler hakkında bilgi sağlayan yöntemler içerir.
| İşlem türü | ICustomMarshaler yöntemi | Description |
|---|---|---|
| Dönüştürme (yerel koddan yönetilen koda) | MarshalNativeToManaged | Yerel verilere yönelik bir işaretçiyi yönetilen bir nesneye dönüştürür. Bu yöntem, bağımsız değişken olarak geçirilen yönetilmeyen arabirimi sıralayan özel bir çalışma zamanı çağrılabilen sarmalayıcı (RCW) döndürür. Marshaller, bu tür için özel RCW örneğini döndürmelidir. |
| Dönüştürme (yönetilen koddan yerel koda) | MarshalManagedToNative | Yönetilen bir nesneyi yerel veri için bir işaretçiye dönüştürür. Bu yöntem, bağımsız değişken olarak geçirilen yönetilen arabirimi sıralayan özel bir COM çağrılabilen sarmalayıcı (CCW) döndürür. Marshaller, o tür için özel olarak tanımlanmış bir CCW örneğini döndürmelidir. |
| Temizleme (yerel koddan) | CleanUpNativeData | Marshaller'ın metodun döndürdüğü yerel veriyi (CCW) temizlemesini sağlar. |
| Temizleme (yönetilen koddan) | CleanUpManagedData | MarshalNativeToManaged yöntemi tarafından döndürülen yönetilen verilerin (RCW) temizlenmesini marshaller'ın sağlamasına olanak tanır. |
| Bilgi (yerel kod hakkında) | GetNativeDataSize | Yönetilmemiş verilerin taşınacak boyutunu döndürür. |
Conversion
ICustomMarshaler.MarshalNativeToManaged
Yerel verilere yönelik bir işaretçiyi yönetilen bir nesneye dönüştürür. Bu yöntem, bağımsız değişken olarak geçirilen yönetilmeyen arabirimi sıralayan özel bir çalışma zamanı çağrılabilen sarmalayıcı (RCW) döndürür. Marshaller, bu tür için özel RCW örneğini döndürmelidir.
ICustomMarshaler.MarshalManagedToNative
Yönetilen bir nesneyi yerel veri için bir işaretçiye dönüştürür. Bu yöntem, bağımsız değişken olarak geçirilen yönetilen arabirimi sıralayan özel bir COM çağrılabilen sarmalayıcı (CCW) döndürür. Marshaller, o tür için özel olarak tanımlanmış bir CCW örneğini döndürmelidir.
Cleanup
ICustomMarshaler.CleanUpNativeData
Marshaller'ın metodun döndürdüğü yerel veriyi (CCW) temizlemesini sağlar.
ICustomMarshaler.CleanUpManagedData
MarshalNativeToManaged yöntemi tarafından döndürülen yönetilen verilerin (RCW) temizlenmesini marshaller'ın sağlamasına olanak tanır.
Boyut bilgileri
ICustomMarshaler.GetNativeDataSize
Yönetilmemiş verilerin taşınacak boyutunu döndürür.
Note
Özel bir marshaller, yerelden yönetilene veya temizleme işlemine marşal ederken son P/Invoke hatasını ayarlayan yöntemleri çağırırsa, Marshal.GetLastWin32Error() ve Marshal.GetLastPInvokeError() tarafından döndürülen değer, hazırlama veya temizleme çağrılarındaki çağrıyı temsil eder. Bu, DllImportAttribute.SetLastErrortrue olarak ayarlandığında, P/Invokes ile özel marshaller'lar kullanırken hataların görmezden gelinmesine neden olabilir. Son P/Invoke hatasını korumak için uygulamadaki Marshal.GetLastPInvokeError() ve Marshal.SetLastPInvokeError(Int32) yöntemlerini kullanınICustomMarshaler.
GetInstance yöntemini uygulama
Arabirimi ICustomMarshaler uygulamanın yanı sıra, özel marshallers, bir static parametresini kabul eden ve dönüş türü GetInstance olan String adlı bir yöntemi uygulamalıdırICustomMarshaler. Bu static yöntem, özel bir marshaller örneğini oluşturmak için ortak dil çalışma zamanının COM birlikte çalışma katmanı tarafından çağrılır.
GetInstance'ye aktarılan dize, yöntemin döndürülen özel marşalleyici için özelleştirmeler yapmasına olanak tanıyan bir çerezdir. Aşağıdaki örnekte en az ama eksiksiz ICustomMarshaler bir uygulama gösterilmektedir.
public class NewOldMarshaler : ICustomMarshaler
{
public static ICustomMarshaler GetInstance(string pstrCookie)
=> new NewOldMarshaler();
public Object MarshalNativeToManaged(IntPtr pNativeData) => throw new NotImplementedException();
public IntPtr MarshalManagedToNative(Object ManagedObj) => throw new NotImplementedException();
public void CleanUpNativeData(IntPtr pNativeData) => throw new NotImplementedException();
public void CleanUpManagedData(Object ManagedObj) => throw new NotImplementedException();
public int GetNativeDataSize() => throw new NotImplementedException();
}
MarshalAsAttribute Uygulamak
Özel bir marshaller kullanmak için, MarshalAsAttribute niteliğini sıralanan parametreye veya alana uygulamanız gerekir.
Ayrıca UnmanagedType.CustomMarshaler numaralandırma değerini MarshalAsAttribute oluşturucuya geçirmeniz gerekir. Ayrıca, alanı aşağıdaki adlandırılmış parametrelerden biriyle belirtmeniz MarshalType gerekir:
MarshalType (gerekli): Özel marshaller'ın derleme nitelikli adı. Ad, özel marshaller'ın ad alanını ve sınıfını içermelidir. Özel marshaller içinde kullanıldığı derlemede tanımlanmamışsa, tanımlandığı derlemenin adını belirtmeniz gerekir.
Note
MarshalTypeRef alanını MarshalType alanı yerine kullanabilirsiniz. MarshalTypeRef belirtilmesi daha kolay bir tür alır.
MarshalCookie (isteğe bağlı): Özel bir marshaller'a iletilen bir tanımlama bilgisi. Tanımlama bilgisini, marshaller'a ek bilgi sağlamak için kullanabilirsiniz. Örneğin, aynı marshaller birden fazla sarmalayıcı sağlamak için kullanılırsa, çerez belirli bir sarmalayıcıyı tanımlar. Tanımlama bilgisi,
GetInstancemarshaller yöntemi yöntemine aktarılır.
MarshalAsAttribute özniteliği, uygun sarmalayıcıyı etkinleştirebilmesi için özel diziciyi tanımlar. Daha sonra ortak dil çalışma zamanındaki birlikte çalışma hizmeti özniteliği inceler ve argümanın (parametre veya alan) ilk kez sıralanması gerektiğinde özel çeviriciyi oluşturur.
Çalışma zamanı, doğru sarmalayıcıyı etkinleştirmek için özel marshaller üzerinde MarshalNativeToManaged ve MarshalManagedToNative yöntemlerini çağırır.
Özel bir marshaller kullan.
Özel marshaller tamamlandığında, bunu belirli bir tür için özel sarmalayıcı olarak kullanabilirsiniz. Aşağıdaki örnekte yönetilen arabirimin tanımı gösterilmektedir IUserData :
interface IUserData
{
void DoSomeStuff(INew pINew);
}
Public Interface IUserData
Sub DoSomeStuff(pINew As INew)
End Interface
Aşağıdaki örnekte, IUserData arabirimi NewOldMarshaler özel marshaller'ı kullanarak yönetilmeyen istemci uygulamalarının bir IOld arabirimini DoSomeStuff yöntemine geçirebilmesini sağlar. Yöntemin DoSomeStuff yönetilen açıklaması, önceki örnekte gösterildiği gibi bir INew arabirim alırken, yönetilmeyen sürümü DoSomeStuff aşağıdaki örnekte gösterildiği gibi bir IOld arabirim işaretçisi alır.
[uuid(9B2BAADA-0705-11D3-A0CD-00C04FA35826)]
library UserLib {
[uuid(9B2BABCD-0705-11D3-A0CD-00C04FA35826)]
interface IUserData : IUnknown
HRESULT DoSomeStuff(IUnknown* pIOld);
}
Yönetilen tanımını dışarı aktararak oluşturulan tür kitaplığı, standart tanım IUserData yerine bu örnekte gösterilen yönetilmeyen tanımı verir. Yönteminin MarshalAsAttributeINew yönetilen tanımında DoSomeStuff bağımsız değişkene uygulanan öznitelik, aşağıdaki örnekte gösterildiği gibi bağımsız değişkenin özel bir marshaller kullandığını gösterir.
using System.Runtime.InteropServices;
Imports System.Runtime.InteropServices
interface IUserData
{
void DoSomeStuff(
[MarshalAs(UnmanagedType.CustomMarshaler,
MarshalType="NewOldMarshaler")]
INew pINew
);
}
Public Interface IUserData
Sub DoSomeStuff( _
<MarshalAs(UnmanagedType.CustomMarshaler, _
MarshalType := "MyCompany.NewOldMarshaler")> pINew As INew)
End Interface
Önceki örneklerde, özniteliğine MarshalAsAttribute sağlanan ilk parametre numaralandırma değeridir UnmanagedType.CustomMarshalerUnmanagedType.CustomMarshaler.
İkinci parametre, özel bir yükleyicinin derleme özellikli ismini sağlayan MarshalType alanıdır. Bu ad, özel marshaller'ın ad alanı ve sınıfından (MarshalType="MyCompany.NewOldMarshaler") oluşur.
Yöntemler
| Name | Description |
|---|---|
| CleanUpManagedData(Object) |
Artık gerekli olmadığında yönetilen verilerin gerekli temizlemesini gerçekleştirir. |
| CleanUpNativeData(IntPtr) |
Artık gerekli olmadığında yönetilmeyen verilerin gerekli temizlemesini gerçekleştirir. |
| GetNativeDataSize() |
Sıralanacak yerel verilerin boyutunu döndürür. |
| MarshalManagedToNative(Object) |
Yönetilen verileri yönetilmeyen verilere dönüştürür. |
| MarshalNativeToManaged(IntPtr) |
Yönetilmeyen verileri yönetilen verilere dönüştürür. |