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.IntPtrEin Zeiger auf einen nicht verwalteten Speicherblock.
structureType
Type: System.TypeDer 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
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