Compartilhar via


Método Marshal.PtrToStructure (IntPtr, Type)

 

Realiza marshal de dados de um bloco não gerenciado de memória para um objeto gerenciado recém-alocado do tipo especificado.

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

Sintaxe

[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

Parâmetros

  • ptr
    Type: System.IntPtr

    Um ponteiro para um bloco não gerenciado de memória.

  • structureType
    Type: System.Type

    O tipo de objeto a ser criado. Esse objeto deve representar uma classe ou estrutura formatada.

Valor Retornado

Type: System.Object

Um objeto gerenciado que contém os dados apontados pelo parâmetro ptr.

Exceções

Exception Condition
ArgumentException

O layout do parâmetro structureType não é sequencial ou explícito.

-ou-

O parâmetro structureType é um tipo genérico.

ArgumentNullException

structureType é null.

MissingMethodException

A classe especificada por structureType não tem um construtor padrão acessível.

Comentários

PtrToStructure is often necessary in COM interop and platform invoke when structure parameters are represented as an System.IntPtr value. You can pass a value type to this overload method. In this case, the returned object is a boxed instance.

Exemplos

The following example creates a managed structure, transfers it to unmanaged memory, and then transfers it back to managed memory using the M:System.Runtime.InteropServices.Marshal.PtrToStructure(System.IntPtr,System.Type) method.

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

The following example demonstrates how to marshal an unmanaged block of memory to a managed structure using the M:System.Runtime.InteropServices.Marshal.PtrToStructure(System.IntPtr,System.Type) method.

Importante

This code assumes 32-bit compilation. Before using a 64-bit compiler, replace M:System.IntPtr.ToInt32 with M:System.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);
}

Segurança

SecurityCriticalAttribute

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

Informações de Versão

Plataforma Universal do Windows
Disponível desde 8
.NET Framework
Disponível desde 1.1
Biblioteca de Classes Portátil
Com suporte no: plataformas portáteis do .NET
Silverlight
Disponível desde 2.0
Windows Phone Silverlight
Disponível desde 7.0
Windows Phone
Disponível desde 8.1

Confira Também

GetTypeAttr
PtrToStructure Sobrecarga
Classe Marshal
Namespace System.Runtime.InteropServices

Retornar ao início