Marshal.PtrToStructure-Methode: (IntPtr, Type)

 

Veröffentlicht: Oktober 2016

Marshallt Daten aus einem nicht verwalteten Speicherblock zu einem neu belegten, verwalteten Objekt des angegebenen Typs.

Namespace:   System.Runtime.InteropServices
Assembly:  mscorlib (in mscorlib.dll)

Syntax

[SecurityCriticalAttribute]
[ComVisibleAttribute(true)]
public static object PtrToStructure(
    IntPtr ptr,
    Type structureType
)
public:
[SecurityCriticalAttribute]
[ComVisibleAttribute(true)]
static Object^ PtrToStructure(
    IntPtr ptr,
    Type^ structureType
)
[<SecurityCriticalAttribute>]
[<ComVisibleAttribute(true)>]
static member PtrToStructure : 
        ptr:nativeint *
        structureType:Type -> Object
<SecurityCriticalAttribute>
<ComVisibleAttribute(True)>
Public Shared Function PtrToStructure (
    ptr As IntPtr,
    structureType As Type
) As Object

Parameter

  • ptr
    Type: System.IntPtr

    Ein Zeiger auf einen nicht verwalteten Speicherblock.

  • structureType
    Type: System.Type

    Der Typ des zu erstellenden Objekts. Dieses Objekt muss eine formatierte Klasse oder eine Struktur darstellen.

Rückgabewert

Type: System.Object

Ein verwaltetes Objekt mit Daten, auf die der ptr-Parameter zeigt.

Ausnahmen

Exception Condition
ArgumentException

Die structureType Parameterlayout ist nicht sequenziell noch explizit.

- oder -

Die structureType Parameter ist ein generischer Typ.

ArgumentNullException

structureType ist null.

MissingMethodException

Die durch angegebene Klasse structureType keinen zugreifbaren Standardkonstruktor.

Hinweise

PtrToStructure wird häufig in COM-Interop und Plattformaufrufe wenn Strukturparameter als dargestellt werden ein System.IntPtr Wert. Sie können einen Werttyp an diese überladene Methode übergeben. In diesem Fall ist das zurückgegebene Objekt eine geschachtelte Instanz.

Beispiele

Im folgenden Beispiel wird eine verwaltete Struktur erstellt, in den nicht verwalteten Speicher und überträgt Sie es dann wieder auf die verwalteten Speicher mithilfe der PtrToStructure Methode.

using System;
using System.Runtime.InteropServices;

public struct Point
{
    public int x;
    public int y;
}

class Example
{

    static void Main()
    {

        // Create a point struct.
        Point p;
        p.x = 1;
        p.y = 1;

        Console.WriteLine("The value of first point is " + p.x + " and " + p.y + ".");

        // Initialize unmanged memory to hold the struct.
        IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(p));

        try
        {

            // Copy the struct to unmanaged memory.
            Marshal.StructureToPtr(p, pnt, false);

            // Create another point.
            Point anotherP;

            // Set this Point to the value of the 
            // Point in unmanaged memory. 
            anotherP = (Point)Marshal.PtrToStructure(pnt, typeof(Point));

            Console.WriteLine("The value of new point is " + anotherP.x + " and " + anotherP.y + ".");

        }
        finally
        {
            // Free the unmanaged memory.
            Marshal.FreeHGlobal(pnt);
        }



    }

}
Imports System
Imports System.Runtime.InteropServices



Public Structure Point
    Public x As Integer
    Public y As Integer
End Structure


Module Example


    Sub Main()

        ' Create a point struct.
        Dim p As Point
        p.x = 1
        p.y = 1

        Console.WriteLine("The value of first point is " + p.x.ToString + " and " + p.y.ToString + ".")

        ' Initialize unmanged memory to hold the struct.
        Dim pnt As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(p))

        Try

            ' Copy the struct to unmanaged memory.
            Marshal.StructureToPtr(p, pnt, False)

            ' Create another point.
            Dim anotherP As Point

            ' Set this Point to the value of the 
            ' Point in unmanaged memory. 
            anotherP = CType(Marshal.PtrToStructure(pnt, GetType(Point)), Point)

            Console.WriteLine("The value of new point is " + anotherP.x.ToString + " and " + anotherP.y.ToString + ".")

        Finally
            ' Free the unmanaged memory.
            Marshal.FreeHGlobal(pnt)
        End Try

    End Sub
End Module

Im folgenden Beispiel wird veranschaulicht, wie einen nicht verwalteten Speicherblock in eine verwaltete Struktur gemarshallt die PtrToStructure Methode.

Wichtig

Dieser Code setzt voraus, 32-Bit-Kompilierung. Ersetzen Sie vor dem Verwenden eines 64-Bit-Compilers, IntPtr.ToInt32 mit IntPtr.ToInt64.

        [StructLayout(LayoutKind.Sequential)]

        public class  INNER

        {

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst =  10)]

            public string field1 = "Test";



        }   

        [StructLayout(LayoutKind.Sequential)]

        public struct OUTER

        {

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst =  10)]

            public string field1;

            [MarshalAs(UnmanagedType.ByValArray, SizeConst =  100)]

            public byte[] inner;

        }





        [DllImport(@"SomeTestDLL.dll")]

        public static extern void CallTest( ref OUTER po);



        static void Main(string[] args)

        {

            OUTER ed = new OUTER();

            INNER[] inn=new INNER[10];

            INNER test = new INNER();

            int iStructSize = Marshal.SizeOf(test);



            int sz =inn.Length * iStructSize;

            ed.inner = new byte[sz];



            try

            {

                CallTest( ref ed);

            }

            catch(Exception e)

            {

                Console.WriteLine(e.Message);

            }

            IntPtr buffer = Marshal.AllocCoTaskMem(iStructSize*10);

            Marshal.Copy(ed.inner,0,buffer,iStructSize*10);



            int iCurOffset = 0;

            for(int i=0;i<10;i++)

            {



                inn[i] = (INNER)Marshal.PtrToStructure(new
IntPtr(buffer.ToInt32()+iCurOffset),typeof(INNER) );

                iCurOffset += iStructSize;

            }

            Console.WriteLine(ed.field1);

            Marshal.FreeCoTaskMem(buffer);

        }
[StructLayout(LayoutKind::Sequential)]
ref class INNER
{
public:
    [MarshalAs(UnmanagedType::ByValTStr,SizeConst=10)]
    String^ field;

    INNER()
    {
        field = "Test";
    }
};

[StructLayout(LayoutKind::Sequential)]
value struct OUTER
{
public:
    [MarshalAs(UnmanagedType::ByValTStr,SizeConst=10)]
    String^ field;

    [MarshalAs(UnmanagedType::ByValArray,SizeConst=100)]
    array<Byte>^ inner;
};

[DllImport("SomeTestDLL.dll")]
static void CallTest(OUTER^ outerStructurePointer);

void static Work()
{
    OUTER outerStructure;
    array<INNER^>^ innerArray = gcnew array<INNER^>(10);
    INNER^ innerStructure = gcnew INNER;
    int structSize = Marshal::SizeOf(innerStructure);
    int size = innerArray->Length * structSize;
    outerStructure.inner = gcnew array<Byte>(size);

    try
    {
        CallTest(outerStructure);
    }
    catch (SystemException^ ex) 
    {
        Console::WriteLine(ex->Message);
    }

    IntPtr buffer = Marshal::AllocCoTaskMem(structSize * 10);
    Marshal::Copy(outerStructure.inner, 0, buffer, structSize * 10);
    int currentOffset = 0;
    for (int i = 0; i < 10; i++)
    {
        innerArray[i] = safe_cast<INNER^>(Marshal::PtrToStructure(
            IntPtr(buffer.ToInt32() + currentOffset),
            INNER::typeid));
        currentOffset += structSize;
    }
    Console::WriteLine(outerStructure.field);
    Marshal::FreeCoTaskMem(buffer);
}

Sicherheit

SecurityCriticalAttribute

requires full trust for the immediate caller. This member cannot be used by partially trusted or transparent code.

Versionsinformationen

Universelle Windows-Plattform
Verfügbar seit 8
.NET Framework
Verfügbar seit 1.1
Portierbare Klassenbibliothek
Unterstützt in: portierbare .NET-Plattformen
Silverlight
Verfügbar seit 2.0
Windows Phone Silverlight
Verfügbar seit 7.0
Windows Phone
Verfügbar seit 8.1

Siehe auch

GetTypeAttr
PtrToStructure Überladen
Marshal-Klasse
System.Runtime.InteropServices-Namespace

Zurück zum Anfang