Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Bu makalede, .NET birlikte çalışma kaynak oluşturucu ile kullanılabilecek özel marshaller'ların farklı "şekilleri" açıklanmaktadır.
Değer dönüştürücüler
Bu bölümde, yönetilen ve yönetilmeyen kod arasında değer türlerinin sıralanması için .NET birlikte çalışma kaynak oluşturucu tarafından kullanılabilecek özel marshaller biçimleri açıklanmaktadır.
Durumsuz olandan yönetilene, yönetilmeyene geçiş
Bu biçimde, oluşturulan kodu, bir değeri yerel koda yönlendirmek için ConvertToUnmanaged'ı veya uygulanabilir olduğunda GetPinnableReference'i çağırır. Oluşturulan kod, marshaller'ın kullanım ömrü sona erdikten sonra yönetilen türle ilişkili yönetilmeyen kaynakları serbest bırakabilmesi için uygun olduğunda Free çağırır.
[CustomMarshaller(typeof(TManaged), MarshalMode.ManagedToUnmanagedIn, typeof(ManagedToNative))]
[CustomMarshaller(typeof(TManaged), MarshalMode.UnmanagedToManagedOut, typeof(ManagedToNative))]
static class TMarshaller
{
public static class ManagedToNative
{
/// <summary>
/// Converts a managed type to an unmanaged representation. May throw exceptions.
/// </summary>
public static TNative ConvertToUnmanaged(TManaged managed);
/// <summary>
/// Optional.
/// Returns a pinnable reference to the unmanaged representation.
/// The reference will be pinned and passed as a pointer to the native code.
/// TOther should be a dereferenced type of TNative.
/// For example, if TNative is `int*`, then TOther should be `int`.
/// </summary>
public static ref TNativeDereferenced GetPinnableReference(TManaged managed);
/// <summary>
/// Optional.
/// Frees any unmanaged resources associated with the marshalling of the managed type.
/// Must not throw exceptions.
/// </summary>
public static void Free(TNative unmanaged);
}
}
Durumsuz, çağıran tarafından ayrılan arabellek ile yönetilmeyen olarak yönetilmiş
Bu şekliyle, üreteç belirtilen boyutta bir arabellek ayırır ve onu ConvertToUnmanaged yöntemine, yerel koda bir değer aktarmak için geçirir. Oluşturulan kod bu arabelleğin yaşam döngüsünü yönetir.
[CustomMarshaller(typeof(TManaged), MarshalMode.ManagedToUnmanagedIn, typeof(ManagedToNative))]
[CustomMarshaller(typeof(TManaged), MarshalMode.UnmanagedToManagedOut, typeof(ManagedToNative))]
static class TMarshaller
{
public static class ManagedToNative
{
/// <summary>
/// The size of the buffer that will be allocated by the generator.
/// </summary>
public static int BufferSize { get; }
/// <summary>
/// Converts a managed type to an unmanaged representation using a caller-allocated buffer.
/// </summary>
public static TNative ConvertToUnmanaged(TManaged managed, Span<byte> callerAllocatedBuffer);
/// <summary>
/// Optional.
/// Frees any unmanaged resources associated with the marshalling of the managed type.
/// Must not throw exceptions.
/// </summary>
public static void Free(TNative unmanaged);
}
}
Durumsuz yönetilmeyen'den yönetilene dönüşüm
[CustomMarshaller(typeof(TManaged), MarshalMode.ManagedToUnmanagedOut, typeof(NativeToManaged))]
[CustomMarshaller(typeof(TManaged), MarshalMode.UnmanagedToManagedIn, typeof(NativeToManaged))]
static class TMarshaller
{
public static class NativeToManaged
{
/// <summary>
/// Converts an unmanaged representation to a managed type. May throw exceptions.
/// </summary>
public static TManaged ConvertToManaged(TNative unmanaged);
/// <summary>
/// Optional.
/// Frees any unmanaged resources associated with the marshalling of the managed type.
/// Must not throw exceptions.
/// </summary>
public static void Free(TNative unmanaged);
}
}
Durum bilgisi olmayan yönetilmeyen, garantili unmarshalling ile yönetilir
Bu şekil, önceki bir marshaller özel durum oluştursa bile, oluşturucuyu özetlenmemiş kodun çağrılacağını garanti edecek şekilde yaymaya yönlendirir. Bu, önceki işlemlerin başarısı ne olursa olsun temizlenmesi veya sonlandırılması gereken türler için yararlıdır.
[CustomMarshaller(typeof(TManaged), MarshalMode.ManagedToUnmanagedOut, typeof(NativeToManaged))]
[CustomMarshaller(typeof(TManaged), MarshalMode.UnmanagedToManagedIn, typeof(NativeToManaged))]
static class TMarshaller
{
public static class NativeToManaged
{
/// <summary>
/// Converts an unmanaged representation to a managed type.
/// Should not throw exceptions.
/// </summary>
public static TManaged ConvertToManagedFinally(TNative unmanaged);
/// <summary>
/// Optional.
/// Frees any unmanaged resources associated with the marshalling of the managed type.
/// Must not throw exceptions.
/// </summary>
public static void Free(TNative unmanaged);
}
}
Durumsuz çift yönlü
Bu şekil, hem yönetilenden yönetilmeyene hem de yönetilmeyenden yönetilene dönüştürmelere olanak tanır ve marshaller durum bilgisizdir. Oluşturucu, yönetilenden yönetilmeyene dönüştürmeler için ConvertToUnmanaged yöntemini ve yönetilmeyenden yönetilene dönüştürmeler için ConvertToManaged yöntemini kullanır.
[CustomMarshaller(typeof(TManaged<,,,...>), MarshalMode.ManagedToUnmanagedRef, typeof(Bidirectional))]
[CustomMarshaller(typeof(TManaged<,,,...>), MarshalMode.UnmanagedToManagedRef, typeof(Bidirectional))]
[CustomMarshaller(typeof(TManaged<,,,...>), MarshalMode.ElementRef, typeof(Bidirectional))]
static class TMarshaller<T, U, V...>
{
public static class Bidirectional
{
// Include members from each of the following:
// - One Stateless Managed->Unmanaged Value shape
// - One Stateless Unmanaged->Managed Value shape
}
}
Durum bilgisi olan yönetilmeyenler tarafından yönetildi
Bu şekil, durum bilgisi taşıyan eşlemeyi yönetimli ortamdan yönetimsiz ortama sağlar. Oluşturulan kod, her parametre için benzersiz bir Marshaller örneği kullanır; böylece Marshaller, sıralama işlemi boyunca durumu koruyabilir.
[CustomMarshaller(typeof(TManaged), MarshalMode.ManagedToUnmanagedIn, typeof(ManagedToNative))]
[CustomMarshaller(typeof(TManaged), MarshalMode.UnmanagedToManagedOut, typeof(ManagedToNative))]
static class TMarshaller
{
public struct ManagedToNative // Can be ref struct
{
/// <summary>
/// Optional constructor.
/// May throw exceptions.
/// </summary>
public ManagedToNative();
/// <summary>
/// Takes a managed type to be converted to an unmanaged representation in ToUnmanaged or GetPinnableReference.
/// </summary>
public void FromManaged(TManaged managed);
/// <summary>
/// Optional.
/// Returns a pinnable reference to the unmanaged representation.
/// The reference will be pinned and passed as a pointer to the native code.
/// TOther should be a dereferenced type of TNative.
/// For example, if TNative is `int*`, then TOther should be `int`.
/// When applicable, this method is preferred to ToUnmanaged for marshalling.
/// </summary>
public ref TIgnored GetPinnableReference();
/// <summary>
/// Optional.
/// Returns a pinnable reference to the unmanaged representation.
/// The reference will be pinned and passed as a pointer to the native code.
/// TOther should be a dereferenced type of TNative.
/// For example, if TNative is `int*`, then TOther should be `int`.
/// When applicable, only this method is called for the marshalling step.
/// May throw exceptions.
/// </summary>
public static ref TOther GetPinnableReference(TManaged managed);
/// <summary>
/// Converts the managed type to an unmanaged representation.
/// May throw exceptions.
/// </summary>
public TNative ToUnmanaged();
/// <summary>
/// Optional.
/// In managed to unmanaged stubs, this method is called after call to the unmanaged code.
/// Must not throw exceptions.
/// </summary>
public void OnInvoked();
/// <summary>
/// Optional.
/// Frees any unmanaged resources associated with the marshalling of the managed type.
/// Must not throw exceptions.
/// </summary>
public void Free();
}
}
Durum bilgisi, çağıran tarafından ayrılan arabellekle yönetilmeyi başardı
Bu şekil, yönetilen ortamdan yönetilmeyen ortama durum bilgisi olan yönlendirme yapılmasına olanak tanır; oluşturucu belirtilen boyutta bir arabellek ayırır ve bunu FromManaged yöntemine iletir. Oluşturulan kod, her parametre için benzersiz bir marshaller örneği kullanır; bu nedenle, marshaller marshalling süreci boyunca durumu koruyabilir.
[CustomMarshaller(typeof(TManaged), MarshalMode.ManagedToUnmanagedIn, typeof(ManagedToNative))]
[CustomMarshaller(typeof(TManaged), MarshalMode.UnmanagedToManagedOut, typeof(ManagedToNative))]
static class TMarshaller
{
public struct ManagedToNative // Can be ref struct
{
/// <summary>
/// The length of the buffer that will be allocated by the generator.
/// </summary>
public static int BufferSize { get; }
/// <summary>
/// Optional constructor.
/// May throw exceptions.
/// </summary>
public ManagedToNative();
/// <summary>
/// Takes a managed type to be converted to an unmanaged representation in ToUnmanaged or GetPinnableReference.
/// May throw exceptions.
/// </summary>
public void FromManaged(TManaged managed, Span<TBuffer> buffer);
/// <summary>
/// Optional.
/// Returns a pinnable reference to the unmanaged representation.
/// The reference will be pinned and passed as a pointer to the native code.
/// TOther should be a dereferenced type of TNative.
/// For example, if TNative is `int*`, then TOther should be `int`.
/// When applicable, this method is preferred to ToUnmanaged for marshalling.
/// </summary>
public ref TIgnored GetPinnableReference();
/// <summary>
/// Optional.
/// Returns a pinnable reference to the unmanaged representation.
/// The reference will be pinned and passed as a pointer to the native code.
/// TOther should be a dereferenced type of TNative.
/// For example, if TNative is `int*`, then TOther should be `int`.
/// When applicable, only this method is called for the marshalling step.
/// May throw exceptions.
public static ref TOther GetPinnableReference(TManaged managed);
/// <summary>
/// Returns the unmanaged representation of the managed value.
/// May throw exceptions.
/// </summary>
public TNative ToUnmanaged();
/// <summary>
/// Optional.
/// In managed to unmanaged stubs, this method is called after call to the unmanaged code.
/// Must not throw exceptions.
/// </summary>
public void OnInvoked();
/// <summary>
/// Optional.
/// Frees any unmanaged resources associated with the marshalling of the managed type.
/// Must not throw exceptions.
/// </summary>
public void Free();
}
}
Durum bilgisine sahip yönetilmeyen sistemden yönetilen sisteme dönüşüm
Bu şekil, yönetilmeyenden yönetilene durum bilgisi olmayan özetlemelere olanak tanır. Oluşturulan kod her parametre için benzersiz bir örnek kullanır, böylece yapı özetleme sırasında durumu koruyabilir.
[CustomMarshaller(typeof(TManaged), MarshalMode.ManagedToUnmanagedOut, typeof(NativeToManaged))]
[CustomMarshaller(typeof(TManaged), MarshalMode.UnmanagedToManagedIn, typeof(NativeToManaged))]
static class TMarshaller
{
public struct NativeToManaged // Can be ref struct
{
/// <summary>
/// Optional constructor.
/// May throw exceptions.
/// </summary>
public NativeToManaged();
/// <summary>
/// Takes an unmanaged representation to be converted to a managed type in ToManaged.
/// Should not throw exceptions.
/// </summary>
public void FromUnmanaged(TNative unmanaged);
/// <summary>
/// Returns the managed value representation of the unmanaged value.
/// May throw exceptions.
/// </summary>
public TManaged ToManaged();
/// <summary>
/// Optional.
/// Frees any unmanaged resources associated with the unmarshalling of the managed type.
/// Must not throw exceptions.
/// </summary>
public void Free();
}
}
Manage edilmeyen veriden yönetilen duruma, garantili çözme işlemiyle geçiş
Bu yapı, oluşturucunun ToManagedFinally yönteminin, daha önceki bir marshaller özel durum oluştursa bile çağrılmasını garanti etmesi koşuluyla, yönetilmeyen bir durumdan yönetilen bir duruma geçişi sağlar. Bu, önceki işlemlerin başarısı ne olursa olsun temizlenmesi veya sonlandırılması gereken türler için yararlıdır.
[CustomMarshaller(typeof(TManaged), MarshalMode.ManagedToUnmanagedOut, typeof(NativeToManaged))]
[CustomMarshaller(typeof(TManaged), MarshalMode.UnmanagedToManagedIn, typeof(NativeToManaged))]
static class TMarshaller
{
public struct NativeToManaged // Can be ref struct
{
/// <summary>
/// Optional constructor.
/// May throw exceptions.
/// </summary>
public NativeToManaged();
/// <summary>
/// Takes an unmanaged representation to be converted to a managed type in ToManagedFinally.
/// Should not throw exceptions.
/// </summary>
public void FromUnmanaged(TNative unmanaged);
/// <summary>
/// Returns the managed value representation of the unmanaged value.
/// Should not throw exceptions.
/// </summary>
public TManaged ToManagedFinally();
/// <summary>
/// Optional.
/// Frees any unmanaged resources associated with the unmarshalling of the managed type.
/// Must not throw exceptions.
/// </summary>
public void Free();
}
}
Durumlu iki yönlü
[CustomMarshaller(typeof(TManaged), MarshalMode.ManagedToUnmanagedRef, typeof(Bidirectional))]
[CustomMarshaller(typeof(TManaged), MarshalMode.UnmanagedToManagedRef, typeof(Bidirectional))]
static class TMarshaller
{
public struct Bidirectional // Can be ref struct
{
// Include members from each of the following:
// - One Stateful Managed->Unmanaged Value shape
// - One Stateful Unmanaged->Managed Value shape
}
}
Koleksiyon düzenleyicileri
Bu bölümde, .NET birlikte çalışma kaynak oluşturucusunun yönetilen ve yönetilmeyen kodlar arasında koleksiyonları sıralamak için desteklediği özel koleksiyon marshaller'larının şekilleri açıklanmaktadır. Bitişik koleksiyon marşalleyicileri, diziler veya listeler gibi yönetilmeyen temsilinde bitişik bir bellek bloğu olarak ifade edilen koleksiyonlar için kullanılır.
Bir koleksiyon türü, öğe türüne göre genel olduğunda (örneğin, List<T>), özel dönüştürücü türü, her iki durumda genellikle iki genel parametreye sahip olur: biri yönetilen öğe türü için ve biri yönetilmeyen öğe türü için. Koleksiyonun öğe türü üzerinde genel olmadığı durumlarda (örneğin, StringCollection), sıralayıcının yönetilmeyen öğe türü için yalnızca tek bir genel parametresi olabilir. Marshaller örnekleri, tipindeki TManagedElement öğelere sahip genel olmayan bir koleksiyon TCollection'un nasıl örneklendirileceğini gösterir. Öğeler farklı değer derleyiciler kullanılarak aktarılabileceğinden, yönetilmeyen element türü TUnmanagedElement üzerinde genel olmalıdır. Koleksiyonun yerel gösterimine TNative denir (genellikle *TUnmanagedElement olarak adlandırılır).
Durumsuz yönetilenden yönetilmeyen duruma
Bu şekilde, oluşturucu yönetilen bir koleksiyonu yönetilmeyen belleğe göre sıralamak için statik yöntemler kullanır. Marshaller yönetilmeyen kapsayıcıyı ayırmak, yönetilen ve yönetilmeyen öğelere erişmek ve isteğe bağlı olarak yönetilmeyen kaynakları boşaltmak için yöntemler sağlamalıdır.
[CustomMarshaller(typeof(TCollection), MarshalMode.ManagedToUnmanagedIn, typeof(ManagedToNative))]
[CustomMarshaller(typeof(TCollection), MarshalMode.UnmanagedToManagedOut, typeof(ManagedToNative))]
[CustomMarshaller(typeof(TCollection), MarshalMode.ElementIn, typeof(ManagedToNative))]
[ContiguousCollectionMarshaller]
static class TMarshaller<TUnmanagedElement> where TUnmanagedElement : unmanaged
{
public static class ManagedToNative
{
/// <summary>
/// Gets the uninitialized unmanaged container for the elements and assigns the number of elements to numElements.
/// The return value is later passed to GetUnmanagedValuesDestination.
/// </summary>
public static TNative AllocateContainerForUnmanagedElements(TCollection managed, out int numElements);
/// <summary>
/// Gets a span of managed elements in the collection.
/// The elements in this span are marshalled by the element marshaller and put into the unmanaged container.
/// </summary>
public static ReadOnlySpan<TManagedElement> GetManagedValuesSource(TCollection managed);
/// <summary>
/// Gets a span of unmanaged elements from the TNative container.
/// The elements in this span are filled with the marshalled values from the managed collection.
/// </summary>
public static Span<TUnmanagedElement> GetUnmanagedValuesDestination(TNative unmanaged, int numElements);
/// <summary>
/// Optional. Returns a pinnable reference to the unmanaged representations of the elements.
/// TOther should be a dereferenced type of TNative.
/// For example, if TNative is `int*`, then TOther should be `int`.
/// </summary>
public static ref TOther GetPinnableReference(TManaged managed);
/// <summary>
/// Optional. Frees unmanaged resources.
/// Should not throw exceptions.
/// </summary>
public static void Free(TNative unmanaged);
}
}
Durum bilgisi olmayan, çağıran tarafından ayrılan arabellekle yönetilenden yönetilmeyene geçiş
Jeneratör bir arabellek ayırır ve bunu hazırlama sırasında kullanmak üzere Marshaller'a geçirir.
[CustomMarshaller(typeof(TCollection), MarshalMode.ManagedToUnmanagedIn, typeof(ManagedToNative))]
[CustomMarshaller(typeof(TCollection), MarshalMode.ElementIn, typeof(ManagedToNative))]
[ContiguousCollectionMarshaller]
static class TMarshaller<TUnmanagedElement> where TUnmanagedElement : unmanaged
{
public static class ManagedToNative
{
/// <summary>
/// The length of the buffer that will be allocated by the generated code and passed to AllocateContainerForUnmanagedElements.
/// </summary>
public static int BufferSize { get; }
/// <summary>
/// Creates the unmanaged container using a caller-allocated buffer, and assigns the number of elements in the collection to numElements.
/// The return value is later passed to GetUnmanagedValuesDestination.
/// </summary>
public static TNative AllocateContainerForUnmanagedElements(TCollection managed, Span<TBuffer> buffer, out int numElements);
/// <summary>
/// Gets a span of managed elements in the collection.
/// The elements in this span are marshalled by the element marshaller and put into the unmanaged container.
/// </summary>
public static ReadOnlySpan<TManagedElement> GetManagedValuesSource(TCollection managed);
/// <summary>
/// Gets a span of unmanaged elements from the TNative container.
/// The elements in this span are filled with the marshalled values from the managed collection.
/// </summary>
public static Span<TUnmanagedElement> GetUnmanagedValuesDestination(TNative unmanaged, int numElements);
/// <summary>
/// Optional. Returns a pinnable reference to the unmanaged representations of the elements.
/// TOther should be a dereferenced type of TNative.
/// For example, if TNative is `int*`, then TOther should be `int`.
/// </summary>
public static ref TOther GetPinnableReference(TManaged managed);
/// <summary>
/// Optional. Frees unmanaged resources.
/// Should not throw exceptions.
/// </summary>
public static void Free(TNative unmanaged);
}
}
Durumsuz yönetilmeyenden yönetilene geçiş
Yönetilmeyen bellekten yönetilen bellek ortamına aktarma işlevini bu yapı gerçekleştirir.
[CustomMarshaller(typeof(TCollection), MarshalMode.ManagedToUnmanagedOut, typeof(NativeToManaged))]
[CustomMarshaller(typeof(TCollection), MarshalMode.UnmanagedToManagedIn, typeof(NativeToManaged))]
[CustomMarshaller(typeof(TCollection), MarshalMode.ElementOut, typeof(NativeToManaged))]
[ContiguousCollectionMarshaller]
static class TMarshaller<TUnmanagedElement> where TUnmanagedElement : unmanaged
{
public static class NativeToManaged
{
/// <summary>
/// Allocates a new collection for unmarshalling.
/// May throw exceptions.
/// </summary>
public static TCollection AllocateContainerForManagedElements(TNative unmanaged, int numElements);
/// <summary>
/// Gets the destination span that unmarshalled managed elements will be written to.
/// May throw exceptions.
/// </summary>
public static Span<TManagedElement> GetManagedValuesDestination(TCollection managed);
/// <summary>
/// Gets the source span of unmanaged elements to unmarshal from.
/// May throw exceptions.
/// </summary>
public static ReadOnlySpan<TUnmanagedElement> GetUnmanagedValuesSource(TNative unmanaged, int numElements);
/// <summary>
/// Optional. Frees unmanaged resources.
/// Should not throw exceptions.
/// </summary>
public static void Free(TNative unmanaged);
}
}
Durum bilgisi olmayan yönetilmeyen, garantili unmarshalling ile yönetilir
Jeneratör, önceki bir marshaller bir istisna oluştursa bile seriden çıkarmanın gerçekleşmesini sağlar.
[CustomMarshaller(typeof(TCollection), MarshalMode.ManagedToUnmanagedOut, typeof(NativeToManaged))]
[ContiguousCollectionMarshaller]
static class TMarshaller<TUnmanagedElement> where TUnmanagedElement : unmanaged
{
public static class NativeToManaged
{
/// <summary>
/// Allocates the managed container for the elements.
/// Should not throw exceptions other than OutOfMemoryException.
/// </summary>
public static TCollection AllocateContainerForManagedElementsFinally(TNative unmanaged, int numElements);
/// <summary>
/// Gets the destination span that unmarshalled managed elements will be written to.
/// May throw exceptions.
/// </summary>
public static Span<TManagedElement> GetManagedValuesDestination(TCollection managed);
/// <summary>
/// Gets the source span of unmanaged elements to unmarshal from.
/// May throw exceptions.
/// </summary>
public static ReadOnlySpan<TUnmanagedElement> GetUnmanagedValuesSource(TNative unmanaged, int numElements);
/// <summary>
/// Optional. Frees unmanaged resources.
/// Should not throw exceptions.
/// </summary>
public static void Free(TNative unmanaged);
}
}
Durum bilgisi olmayan çift yönlü
Bu şekil hem yönetilenden yönetilmeyene hem de yönetilmeyenden yönetilene dönüştürmeleri destekler.
[CustomMarshaller(typeof(TCollection), MarshalMode.ManagedToUnmanagedRef, typeof(Bidirectional))]
[CustomMarshaller(typeof(TCollection), MarshalMode.UnmanagedToManagedRef, typeof(Bidirectional))]
[CustomMarshaller(typeof(TCollection), MarshalMode.ElementRef, typeof(Bidirectional))]
[ContiguousCollectionMarshaller]
static class TMarshaller<TUnmanagedElement> where TUnmanagedElement : unmanaged
{
public static class Bidirectional
{
// Include members from each of the following:
// - One Stateless Managed->Unmanaged Linear Collection shape
// - One Stateless Unmanaged->Managed Linear Collection shape
}
}
Durum bilgisi olan yönetilmeyenler tarafından yönetildi
Bu şekil, marshaller'ın marshalling işlemi genelinde durumu korumasını sağlar.
[CustomMarshaller(typeof(TCollection), MarshalMode.ManagedToUnmanagedIn, typeof(ManagedToNative))]
[CustomMarshaller(typeof(TCollection), MarshalMode.UnmanagedToManagedOut, typeof(ManagedToNative))]
[ContiguousCollectionMarshaller]
static class TMarshaller<TUnmanagedElement> where TUnmanagedElement : unmanaged
{
public struct ManagedToNative // Can be ref struct
{
/// <summary>
/// Optional constructor.
/// May throw exceptions.
/// </summary>
public ManagedToNative(); // Optional, can throw exceptions.
/// <summary>
/// Takes a managed collection to be converted to an unmanaged representation in ToUnmanaged or GetPinnableReference.
/// </summary>
public void FromManaged(TCollection collection); // Can throw exceptions.
/// <summary>
/// Gets the source span of managed elements to marshal.
/// May throw exceptions.
/// </summary>
public ReadOnlySpan<TManagedElement> GetManagedValuesSource(); // Can throw exceptions.
/// <summary>
/// Gets the destination span of unmanaged elements to marshal to.
/// May throw exceptions.
/// </summary>
public Span<TUnmanagedElement> GetUnmanagedValuesDestination(); // Can throw exceptions.
/// <summary>
/// Optional.
/// Gets a pinnable reference to the unmanaged representation.
/// The reference will be pinned and passed as a pointer to the native code.
/// TOther should be a dereferenced type of TNative.
/// For example, if TNative is `int*`, then TOther should be `int`.
/// When applicable, this method is preferred to ToUnmanaged for marshalling.
/// May throw exceptions.
/// </summary>
public ref TOther GetPinnableReference(); // Optional. Can throw exceptions.
/// <summary>
/// Optional.
/// Gets a pinnable reference to the unmanaged representation.
/// The reference will be pinned and passed as a pointer to the native code.
/// TOther should be a dereferenced type of TNative.
/// For example, if TNative is `int*`, then TOther should be `int`.
/// When applicable, this method is preferred to the instance version and ToUnmanaged for marshalling.
/// May throw exceptions.
/// </summary>
public static ref TOther GetPinnableReference(TCollection collection); // Optional. Can throw exceptions. Result pinnned and passed to Invoke.
/// <summary>
/// Converts the managed collection to an unmanaged representation.
/// May throw exceptions.
/// </summary>
public TNative ToUnmanaged(); // Can throw exceptions.
/// <summary>
/// Optional.
/// In managed to unmanaged stubs, this method is called after call to the unmanaged code.
/// Must not throw exceptions.
/// </summary>
public void OnInvoked(); // Optional. Should not throw exceptions.
}
}
Durum bilgisi, çağıran tarafından ayrılan arabellekle yönetilmeyi başardı
[CustomMarshaller(typeof(TCollection), MarshalMode.ManagedToUnmanagedIn, typeof(ManagedToNative))]
[ContiguousCollectionMarshaller]
static class TMarshaller<TUnmanagedElement> where TUnmanagedElement : unmanaged
{
public struct ManagedToNative // Can be ref struct
{
/// <summary>
/// The length of the buffer that will be allocated by the generated code and passed to FromManaged.
/// </summary>
public static int BufferSize { get; }
/// <summary>
/// Optional constructor.
/// May throw exceptions.
/// </summary>
public ManagedToNative();
/// <summary>
/// Takes a managed collection to be converted to an unmanaged representation in ToUnmanaged or GetPinnableReference.
/// The caller-allocated buffer is passed to this method.
/// </summary>
public void FromManaged(TCollection collection, Span<TBuffer> buffer);
/// <summary>
/// Gets the source span of managed elements to marshal.
/// May throw exceptions.
/// </summary>
public ReadOnlySpan<TManagedElement> GetManagedValuesSource();
/// <summary>
/// Gets the destination span of unmanaged elements to marshal to.
/// May throw exceptions.
/// </summary>
public Span<TUnmanagedElement> GetUnmanagedValuesDestination();
/// <summary>
/// Optional.
/// Gets a pinnable reference to the unmanaged representation.
/// The reference will be pinned and passed as a pointer to the native code.
/// TOther should be a dereferenced type of TNative.
/// For example, if TNative is `int*`, then TOther should be `int`.
/// When applicable, this method is preferred to ToUnmanaged for marshalling.
/// May throw exceptions.
/// </summary>
public ref TOther GetPinnableReference();
/// <summary>
/// Optional.
/// Gets a pinnable reference to the unmanaged representation.
/// The reference will be pinned and passed as a pointer to the native code.
/// TOther should be a dereferenced type of TNative.
/// For example, if TNative is `int*`, then TOther should be `int`.
/// When applicable, this method is preferred to the instance GetPinnableReference and ToUnmanaged for marshalling.
/// May throw exceptions.
/// </summary>
public static ref TOther GetPinnableReference(TCollection collection);
/// <summary>
/// Converts the managed collection to an unmanaged representation.
/// May throw exceptions.
/// </summary>
public TNative ToUnmanaged();
/// <summary>
/// Optional.
/// In managed to unmanaged stubs, this method is called after call to the unmanaged code.
/// Must not throw exceptions.
/// </summary>
public void OnInvoked();
}
}
Durum bilgisine sahip yönetilmeyen sistemden yönetilen sisteme dönüşüm
Bu yapı, seri çözme işlemi sırasında marshaller’ın durumu korumasını sağlar.
[CustomMarshaller(typeof(TCollection), MarshalMode.ManagedToUnmanagedOut, typeof(NativeToManaged))]
[CustomMarshaller(typeof(TCollection), MarshalMode.UnmanagedToManagedIn, typeof(NativeToManaged))]
[ContiguousCollectionMarshaller]
static class TMarshaller<TUnmanagedElement> where TUnmanagedElement : unmanaged
{
public struct NativeToManaged // Can be ref struct
{
/// <summary>
/// Optional constructor.
/// May throw exceptions.
/// </summary>
public NativeToManaged();
/// <summary>
/// Takes an unmanaged collection to be converted to a managed representation in ToManaged.
/// Should not throw exceptions.
/// </summary>
public void FromUnmanaged(TNative value);
/// <summary>
/// Gets the source span of unmanaged elements to unmarshal from.
/// May throw exceptions.
/// </summary>
public ReadOnlySpan<TUnmanagedElement> GetUnmanagedValuesSource(int numElements);
/// <summary>
/// Gets the destination span that unmarshalled managed elements will be written to.
/// May throw exceptions.
/// </summary>
public Span<TManagedElement> GetManagedValuesDestination(int numElements);
/// <summary>
/// Returns the managed value representation of the unmanaged value.
/// May throw exceptions.
/// </summary>
public TCollection ToManaged();
/// <summary>
/// Optional. Should not throw exceptions.
/// </summary>
public void Free();
}
}
Manage edilmeyen veriden yönetilen duruma, garantili çözme işlemiyle geçiş
[CustomMarshaller(typeof(TCollection), MarshalMode.ManagedToUnmanagedOut, typeof(NativeToManaged))]
[ContiguousCollectionMarshaller]
static class TMarshaller<TUnmanagedElement> where TUnmanagedElement : unmanaged
{
public struct NativeToManaged // Can be ref struct
{
/// <summary>
/// Optional constructor.
/// May throw exceptions.
/// </summary>
public NativeToManaged(); // Optional, can throw exceptions.
/// <summary>
/// Takes an unmanaged collection to be converted to a managed representation in ToManagedFinally.
/// Should not throw exceptions.
/// </summary>
public void FromUnmanaged(TNative value);
/// <summary>
/// Gets the source span of unmanaged elements to unmarshal from.
/// May throw exceptions.
/// </summary>
public ReadOnlySpan<TUnmanagedElement> GetUnmanagedValuesSource(int numElements);
/// <summary>
/// Gets the destination span that unmarshalled managed elements will be written to.
/// May throw exceptions.
/// </summary>
public Span<TManagedElement> GetManagedValuesDestination(int numElements);
/// <summary>
/// Returns the managed value representation of the unmanaged value.
/// Should not throw exceptions.
/// </summary>
public TCollection ToManagedFinally();
/// <summary>
/// Optional. Should not throw exceptions.
/// </summary>
public void Free();
}
}
Durumlu iki yönlü
[CustomMarshaller(typeof(TCollection), MarshalMode.ManagedToUnmanagedRef, typeof(Bidirectional))]
[CustomMarshaller(typeof(TCollection), MarshalMode.UnmanagedToManagedRef, typeof(Bidirectional))]
[ContiguousCollectionMarshaller]
static class TMarshaller<TUnmanagedElement> where TUnmanagedElement : unmanaged
{
public struct Bidirectional // Can be ref struct
{
// Include members from each of the following:
// - One Stateful Managed->Unmanaged Contiguous Collection shape
// - One Stateful Unmanaged->Managed Contiguous Collection shape
}
}