System.Runtime.InteropServices.ICustomMarshaler arabirimi
Bu makale, bu API'nin başvuru belgelerine ek açıklamalar sağlar.
Arabirimi, ICustomMarshaler yöntem çağrılarını işlemek için özel sarmalayıcılar sağlar.
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ı sıralama davranışı tanıtır veya Bileşen Nesne Modeli'ne (COM) farklı bir şekilde kullanıma sunulan bir arabiriminiz varsa, birlikte çalışma marshaller'ını kullanmak yerine özel bir marshaller tasarlayabilirsiniz. Özel bir marshaller kullanarak yeni .NET Framework bileşenleriyle mevcut COM bileşenleri arasındaki ayrımı en aza indirebilirsiniz.
Örneğin, adlı INew
bir 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 adlı IOld
iyi bilinen bir COM arabiriminin arabirimle aynı işlevselliği sağladığını INew
varsayalım. Özel bir marshaller tasarlayarak, yalnızca çağrıları arabirimin IOld
yönetilen uygulamasına temsilci olarak veren yönetilmeyen bir uygulaması INew
sağlayabilirsiniz. Bu nedenle, özel marshaller yönetilen ve yönetilmeyen arabirimler arasında bir köprü işlevi görür.
Not
Yönetilen koddan yalnızca dağıtım arabirimindeki yönetilmeyen koda çağrılırken özel marshallers çağrılmaz.
Hazırlama türünü tanımlama
Ö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 kodunuzda yer alan arabirimin C++ tanımını içerir.
ICustomMarshaler arabirimini uygulama
Özel marshaller'ınız, çalışma zamanına ICustomMarshaler uygun sarmalayıcıları sağlamak için 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
Arabirim, ICustomMarshaler dönüştürme desteği, temizleme desteği ve sıralanacak veriler hakkında bilgi sağlayan yöntemler içerir.
İşlem türü | ICustomMarshaler yöntemi | Açıklama |
---|---|---|
Dönüştürme (yerel koddan yönetilen koda) | MarshalNativeToManaged | Yerel verilere yönelik bir işaretçiyi yönetilen bir nesneye sıralar. 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 nesneyi yerel verilere yönelik bir işaretçiye göre sıralar. 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, bu tür için özel CCW örneğini döndürmelidir. |
Temizleme (yerel koddan) | CleanUpNativeData | Marshaller'ın yöntemi tarafından döndürülen yerel verileri (CCW) temizlemesini MarshalManagedToNative sağlar. |
Temizleme (yönetilen koddan) | CleanUpManagedData | Marshaller'ın yöntemi tarafından döndürülen yönetilen verileri (RCW) temizlemesini MarshalNativeToManaged sağlar. |
Bilgi (yerel kod hakkında) | GetNativeDataSize | Sıralanacak yönetilmeyen verilerin boyutunu döndürür. |
Dönüştürme
ICustomMarshaler.MarshalNativeToManaged
Yerel verilere yönelik bir işaretçiyi yönetilen bir nesneye sıralar. 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 nesneyi yerel verilere yönelik bir işaretçiye göre sıralar. 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, bu tür için özel CCW örneğini döndürmelidir.
Temizleme
ICustomMarshaler.CleanUpNativeData
Marshaller'ın yöntemi tarafından döndürülen yerel verileri (CCW) temizlemesini MarshalManagedToNative sağlar.
ICustomMarshaler.CleanUpManagedData
Marshaller'ın yöntemi tarafından döndürülen yönetilen verileri (RCW) temizlemesini MarshalNativeToManaged sağlar.
Boyut bilgileri
ICustomMarshaler.GetNativeDataSize
Sıralanacak yönetilmeyen verilerin boyutunu döndürür.
Not
Özel bir marshaller, yerelden yönetilene veya temizleme işlemine sıralarken son P/Invoke hatasını ayarlayan yöntemleri çağırırsa, tarafından Marshal.GetLastWin32Error() döndürülen değer ve Marshal.GetLastPInvokeError() , hazırlama veya temizleme çağrılarındaki çağrıyı temsil eder. Bu, P/Invokes ile özel marshaller'ları DllImportAttribute.SetLastError olarak ayarlandığında hataların kaçırılmasına true
neden olabilir. Son P/Invoke hatasını korumak için uygulamadaki ICustomMarshaler ve Marshal.SetLastPInvokeError(Int32) yöntemlerini kullanınMarshal.GetLastPInvokeError().
GetInstance yöntemini uygulama
Arabirimi uygulamaya ICustomMarshaler ek olarak, özel marshallers parametresi olarak kabul eden String ve dönüş türüne ICustomMarshalersahip adlı GetInstance
bir yöntem uygulamalıdırstatic
. Bu static
yöntem, özel bir marshaller örneğini başlatmak için ortak dil çalışma zamanının COM birlikte çalışma katmanı tarafından çağrılır. geçirilen GetInstance
dize, yöntemin döndürülen özel marshaller'ı özelleştirmek için kullanabileceği bir tanımlama bilgisidir. 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 Uygulama
Özel bir marshaller kullanmak için, özniteliğini MarshalAsAttribute sıralanan parametreye veya alana uygulamanız gerekir.
Ayrıca numaralandırma değerini oluşturucuya MarshalAsAttribute geçirmeniz UnmanagedType.CustomMarshaler 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.
Not
Alanı yerine MarshalType alanını kullanabilirsinizMarshalTypeRef. MarshalTypeRef daha kolay belirtilmesi gereken bir tür alır.
MarshalCookie (isteğe bağlı): Özel marshaller'a geçirilen bir tanımlama bilgisi. Tanımlama bilgisini, marshaller'a ek bilgi sağlamak için kullanabilirsiniz. Örneğin, aynı marshaller bir dizi sarmalayıcı sağlamak için kullanılırsa, tanımlama bilgisi belirli bir sarmalayıcıyı tanımlar. Tanımlama bilgisi, marshaller yöntemine geçirilir
GetInstance
.
MarshalAsAttribute özniteliği, uygun sarmalayıcıyı etkinleştirebilmesi için özel marshaller'ı tanımlar. Daha sonra ortak dil çalışma zamanının birlikte çalışma hizmeti özniteliğini inceler ve bağımsız değişkenin (parametre veya alan) ilk kez sıralanması gerektiğinde özel marshaller'ı oluşturur.
Çalışma zamanı, çağrıyı MarshalNativeToManaged işlemek üzere doğru sarmalayıcıyı etkinleştirmek için özel marshaller'da ve MarshalManagedToNative yöntemlerini çağırır.
Özel bir marshaller kullanma
Ö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 arabirim, IUserData
yönetilmeyen istemci uygulamalarının NewOldMarshaler
yöntemine bir IOld
arabirim DoSomeStuff
geçirmesini sağlamak için özel marshaller'ı kullanır. 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 marshaller'ın derleme nitelikli adını sağlayan alanıdır MarshalType . Bu ad, özel marshallerMarshalType="MyCompany.NewOldMarshaler"
() ad alanı ve sınıfından oluşur.
Geri Bildirim
https://aka.ms/ContentUserFeedback.
Çok yakında: 2024 boyunca, içerik için geri bildirim mekanizması olarak GitHub Sorunları’nı kullanımdan kaldıracak ve yeni bir geri bildirim sistemiyle değiştireceğiz. Daha fazla bilgi için bkz.Gönderin ve geri bildirimi görüntüleyin