IntPtr Struct-datatyp

Definition

Representerar ett signerat heltal där bitbredden är samma som en pekare.

public value class IntPtr
public value class IntPtr : System::Runtime::Serialization::ISerializable
public value class IntPtr : IEquatable<IntPtr>, System::Runtime::Serialization::ISerializable
public struct IntPtr
[System.Serializable]
public struct IntPtr : System.Runtime.Serialization.ISerializable
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public struct IntPtr : System.Runtime.Serialization.ISerializable
public struct IntPtr : System.Runtime.Serialization.ISerializable
public readonly struct IntPtr : IEquatable<IntPtr>, System.Runtime.Serialization.ISerializable
type nativeint = struct
[<System.Serializable>]
type nativeint = struct
    interface ISerializable
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type nativeint = struct
    interface ISerializable
type nativeint = struct
    interface ISerializable
Public Structure IntPtr
Public Structure IntPtr
Implements ISerializable
Public Structure IntPtr
Implements IEquatable(Of IntPtr), ISerializable
Arv
IntPtr
Attribut
Implementeringar

Exempel

I följande exempel används hanterade pekare för att omvända tecknen i en matris. När ett objekt har initierats String och dess längd har hämtats gör det följande:

  1. Marshal.StringToHGlobalAnsi Anropar metoden för att kopiera Unicode-strängen till ohanterat minne som ett ANSI-tecken (en byte). Metoden returnerar ett IntPtr objekt som pekar på början av den ohanterade strängen. I det Visual Basic exemplet används den här pekaren direkt. I exemplen C++, F# och C# skickas den till en pekare till en byte.

  2. Marshal.AllocHGlobal Anropar metoden för att allokera samma antal byte som den ohanterade strängen upptar. Metoden returnerar ett IntPtr objekt som pekar på början av det ohanterade minnesblocket. I det Visual Basic exemplet används den här pekaren direkt. I exemplen C++, F# och C# skickas den till en pekare till en byte.

  3. I Visual Basic-exemplet definieras en variabel med namnet offset som är lika med längden på ANSI-strängen. Den används för att fastställa förskjutningen till ohanterat minne som nästa tecken i ANSI-strängen kopieras till. Eftersom dess startvärde är längden på strängen kopierar kopieringsåtgärden ett tecken från början av strängen till slutet av minnesblocket.

    I exemplen ToPointer C#, F# och C++ anropas metoden för att hämta en ohanterad pekare till startadressen för strängen och det ohanterade minnesblocket, och de lägger till en mindre än längden på strängen till ansi-strängens startadress. Eftersom den ohanterade strängpekaren nu pekar mot slutet av strängen kopierar kopieringsåtgärden ett tecken från slutet av strängen till början av minnesblocket.

  4. Använder en loop för att kopiera varje tecken från strängen till det ohanterade minnesblocket.

    I Visual Basic-exemplet anropas metoden Marshal.ReadByte(IntPtr, Int32) för att läsa bytet (eller ett byte) vid en angiven förskjutning från den hanterade pekaren till ANSI-strängen. Förskjutningen ökas med varje iteration av loopen. Den anropar Marshal.WriteByte(IntPtr, Int32, Byte) sedan metoden för att skriva bytet till den minnesadress som definieras av startadressen för det ohanterade blocket med minne plus offset. Det minskar offsetsedan .

    Exemplen C#, F# och C++ utför kopieringsåtgärden och minskar sedan pekaren till adressen för nästa plats i den ohanterade ANSI-strängen och ökar pekaren till nästa adress i det ohanterade blocket.

  5. Alla exempel anropar Marshal.PtrToStringAnsi för att konvertera det ohanterade minnesblocket som innehåller den kopierade ANSI-strängen till ett hanterat Unicode-objekt String .

  6. När du har visat de ursprungliga och omvända strängarna anropar FreeHGlobal alla exempel metoden för att frigöra det minne som allokerats för den ohanterade ANSI-strängen och det ohanterade minnesblocket.

using namespace System;
using namespace System::Runtime::InteropServices;

class NotTooSafeStringReverse
{
public:
    static void Main()
    {
        String^ stringA = "I seem to be turned around!";
        int copylen = stringA->Length;

        // Allocate HGlobal memory for source and destination strings
        IntPtr sptr = Marshal::StringToHGlobalAnsi(stringA);
        IntPtr dptr = Marshal::AllocHGlobal(copylen + 1);

        char *src = (char *)sptr.ToPointer();
        char *dst = (char *)dptr.ToPointer();

        if (copylen > 0)
        {
            // set the source pointer to the end of the string
            // to do a reverse copy.
            src += copylen - 1;

            while (copylen-- > 0)
            {
                *dst++ = *src--;
            }
            *dst = 0;
        }
        String^ stringB = Marshal::PtrToStringAnsi(dptr);

        Console::WriteLine("Original:\n{0}\n", stringA);
        Console::WriteLine("Reversed:\n{0}", stringB);

        // Free HGlobal memory
        Marshal::FreeHGlobal(dptr);
        Marshal::FreeHGlobal(sptr);
    }
};

int main()
{
    NotTooSafeStringReverse::Main();
}

// The progam has the following output:
//
// Original:
// I seem to be turned around!
//
// Reversed:
// !dnuora denrut eb ot mees I
using System;
using System.Runtime.InteropServices;

class NotTooSafeStringReverse
{
    static public void Main()
    {
        string stringA = "I seem to be turned around!";
        int copylen = stringA.Length;

        // Allocate HGlobal memory for source and destination strings
        IntPtr sptr = Marshal.StringToHGlobalAnsi(stringA);
        IntPtr dptr = Marshal.AllocHGlobal(copylen + 1);

        // The unsafe section where byte pointers are used.
        unsafe
        {
            byte *src = (byte *)sptr.ToPointer();
            byte *dst = (byte *)dptr.ToPointer();

            if (copylen > 0)
            {
                // set the source pointer to the end of the string
                // to do a reverse copy.
                src += copylen - 1;

                while (copylen-- > 0)
                {
                    *dst++ = *src--;
                }
                *dst = 0;
            }
        }
        string stringB = Marshal.PtrToStringAnsi(dptr);

        Console.WriteLine("Original:\n{0}\n", stringA);
        Console.WriteLine("Reversed:\n{0}", stringB);

        // Free HGlobal memory
        Marshal.FreeHGlobal(dptr);
        Marshal.FreeHGlobal(sptr);
    }
}

// The progam has the following output:
//
// Original:
// I seem to be turned around!
//
// Reversed:
// !dnuora denrut eb ot mees I
#nowarn "9"
open System.Runtime.InteropServices
open FSharp.NativeInterop

[<EntryPoint>]
let main _ = 
    let stringA = "I seem to be turned around!"
    let mutable copylen = stringA.Length

    // Allocate HGlobal memory for source and destination strings
    let sptr = Marshal.StringToHGlobalAnsi stringA
    let dptr = Marshal.AllocHGlobal(copylen + 1)

    let mutable src: byte nativeptr = sptr.ToPointer() |> NativePtr.ofVoidPtr
    let mutable dst: byte nativeptr = dptr.ToPointer() |> NativePtr.ofVoidPtr

    if copylen > 0 then
        // set the source pointer to the end of the string
        // to do a reverse copy.
        src <- 
            NativePtr.toNativeInt src + nativeint (copylen - 1) 
            |> NativePtr.ofNativeInt

        while copylen > 0 do
            copylen <- copylen - 1
            NativePtr.read src |> NativePtr.write dst
            dst <- NativePtr.toNativeInt dst + 1n |> NativePtr.ofNativeInt
            src <- NativePtr.toNativeInt src - 1n |> NativePtr.ofNativeInt
        NativePtr.write dst 0uy

    let stringB = Marshal.PtrToStringAnsi dptr

    printfn $"Original:\n{stringA}\n"
    printfn $"Reversed:\n{stringB}"

    // Free HGlobal memory
    Marshal.FreeHGlobal dptr
    Marshal.FreeHGlobal sptr
    0

// The progam has the following output:
//
// Original:
// I seem to be turned around!
//
// Reversed:
// !dnuora denrut eb ot mees I
Imports System.Runtime.InteropServices

Public Module Example
    Public Sub Main()
        Dim stringA As String = "I seem to be turned around!"
        Dim copylen As Integer = stringA.Length

        ' Allocate HGlobal memory for source and destination strings
        Dim sptr As IntPtr = Marshal.StringToHGlobalAnsi(stringA)
        Dim dptr As IntPtr = Marshal.AllocHGlobal(copylen)
        Dim offset As Integer = copylen - 1

         For ctr As Integer = 0 To copylen - 1
            Dim b As Byte = Marshal.ReadByte(sptr, ctr)
            Marshal.WriteByte(dptr, offset, b)
            offset -= 1
         Next

        Dim stringB As String = Marshal.PtrToStringAnsi(dptr)

        Console.WriteLine("Original:{1}{0}{1}", stringA, vbCrLf)
        Console.WriteLine("Reversed:{1}{0}{1}", stringB, vbCrLf)

        ' Free HGlobal memory
        Marshal.FreeHGlobal(dptr)
        Marshal.FreeHGlobal(sptr)
    End Sub
End Module
' The example displays the following output:
'       Original:
'       I seem to be turned around!
'
'       Reversed:
'       !dnuora denrut eb ot mees I

Kommentarer

Typen IntPtr är utformad för att vara ett heltal vars storlek är samma som en pekare. En instans av den här typen förväntas alltså vara 32 bitar i en 32-bitarsprocess och 64 bitar i en 64-bitarsprocess.

Typen IntPtr kan användas av språk som stöder pekare och som ett vanligt sätt att referera till data mellan språk som inte stöder pekare.

IntPtr objekt kan också användas för att lagra referenser. Till exempel används instanser av IntPtr i stor utsträckning i System.IO.FileStream klassen för att lagra filhandtag.

Note

Att använda IntPtr som pekare eller handtag är felbenäget och osäkert. Det är helt enkelt en heltalstyp som kan användas som ett utbytesformat för pekare och handtag på grund av samma storlek. Utanför specifika utbyteskrav, till exempel för att skicka data till ett språk som inte stöder pekare, bör en korrekt typad pekare användas för att representera pekare och SafeHandle användas för att representera referenser.

Den här typen implementerar ISerializable. I .NET 5 och senare versioner implementerar den här typen även gränssnitten IFormattable. I .NET 7 och senare versioner implementerar den här typen även gränssnitten IBinaryInteger<TSelf>, IMinMaxValue<TSelf> och ISignedNumber<TSelf>.

I C# från version 9.0 kan du använda den inbyggda nint typen för att definiera inbyggda heltal. Den här typen representeras av IntPtr typen internt och tillhandahåller åtgärder och konverteringar som är lämpliga för heltalstyper. Mer information finns i typerna nint och nuint.

I C# från och med version 11 och när .NET 7 eller senare körs är nint ett alias för IntPtr på samma sätt som int är ett alias för Int32.

Konstruktorer

Name Description
IntPtr(Int32)

Initierar en ny instans av IntPtr att använda det angivna 32-bitars signerade heltalet.

IntPtr(Int64)

Initierar en ny instans av IntPtr att använda det angivna 64-bitars signerade heltalet.

IntPtr(Void*)

Initierar en ny instans av IntPtr att använda den angivna pekaren till en ospecificerad typ.

Fält

Name Description
Zero

Ett skrivskyddat fält som representerar ett signerat heltal som har initierats till noll.

Egenskaper

Name Description
Size

Hämtar storleken på den här instansen.

Metoder

Name Description
Add(IntPtr, Int32)

Lägger till en förskjutning i ett signerat heltal.

Equals(Object)

Returnerar ett värde som anger om den här instansen är lika med ett angivet objekt.

GetHashCode()

Returnerar hash-koden för den här instansen.

Subtract(IntPtr, Int32)

Subtraherar en förskjutning från ett signerat heltal.

ToInt32()

Konverterar värdet för den här instansen till ett 32-bitars signerat heltal.

ToInt64()

Konverterar värdet för den här instansen till ett 64-bitars signerat heltal.

ToPointer()

Konverterar värdet för den här instansen till en pekare till en ospecificerad typ.

ToString()

Konverterar det aktuella objektets numeriska värde IntPtr till motsvarande strängrepresentation.

ToString(String)

Konverterar det aktuella objektets numeriska värde IntPtr till motsvarande strängrepresentation.

Operatorer

Name Description
Addition(IntPtr, Int32)

Lägger till en förskjutning i ett signerat heltal.

Equality(IntPtr, IntPtr)

Avgör om två angivna instanser av IntPtr är lika med.

Explicit(Int32 to IntPtr)

Konverterar värdet för ett 32-bitars signerat heltal till ett IntPtr.

Explicit(Int64 to IntPtr)

Konverterar värdet för ett 64-bitars signerat heltal till ett IntPtr.

Explicit(IntPtr to Int32)

Konverterar värdet för det angivna IntPtr till ett 32-bitars signerat heltal.

Explicit(IntPtr to Int64)

Konverterar värdet för det angivna IntPtr till ett 64-bitars signerat heltal.

Explicit(IntPtr to Void*)

Konverterar värdet för den angivna IntPtr till en pekare till en ospecificerad typ.

Detta API uppfyller inte CLS.

Explicit(Void* to IntPtr)

Konverterar den angivna pekaren till en ospecificerad typ till en IntPtr.

Detta API uppfyller inte CLS.

Inequality(IntPtr, IntPtr)

Avgör om två angivna instanser av IntPtr inte är lika med.

Subtraction(IntPtr, Int32)

Subtraherar en förskjutning från ett signerat heltal.

Explicita gränssnittsimplementeringar

Name Description
IEquatable<IntPtr>.Equals(IntPtr)

Returnerar ett värde som anger om den här instansen är lika med ett annat signerat heltal.

ISerializable.GetObjectData(SerializationInfo, StreamingContext)

Fyller i ett SerializationInfo objekt med de data som behövs för att serialisera det aktuella IntPtr objektet.

Gäller för

Trådsäkerhet

Den här typen är trådsäker.

Se även