IntPtr Struct

Definizione

Rappresenta un intero con segno in cui la larghezza del bit è uguale a un puntatore.

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
Ereditarietà
IntPtr
Attributi
Implementazioni

Esempio

Nell'esempio seguente vengono usati puntatori gestiti per invertire i caratteri in una matrice. Dopo l'inizializzazione di un String oggetto e la relativa lunghezza, esegue le operazioni seguenti:

  1. Chiama il Marshal.StringToHGlobalAnsi metodo per copiare la stringa Unicode nella memoria non gestita come carattere ANSI (un byte). Il metodo restituisce un IntPtr oggetto che punta all'inizio della stringa non gestita. L'esempio di Visual Basic usa direttamente questo puntatore; negli esempi C++, F# e C# viene eseguito il cast a un puntatore a un byte.

  2. Chiama il Marshal.AllocHGlobal metodo per allocare lo stesso numero di byte occupato dalla stringa non gestita. Il metodo restituisce un IntPtr oggetto che punta all'inizio del blocco di memoria non gestito. L'esempio di Visual Basic usa direttamente questo puntatore; negli esempi C++, F# e C# viene eseguito il cast a un puntatore a un byte.

  3. Nell'esempio Visual Basic viene definita una variabile denominata offset uguale alla lunghezza della stringa ANSI. Viene usato per determinare l'offset in memoria non gestita in cui viene copiato il carattere successivo nella stringa ANSI. Poiché il valore iniziale è la lunghezza della stringa, l'operazione di copia copia copia un carattere dall'inizio della stringa alla fine del blocco di memoria.

    Gli esempi C#, F# e C++ chiamano il ToPointer metodo per ottenere un puntatore non gestito all'indirizzo iniziale della stringa e al blocco di memoria non gestito e aggiungono uno minore della lunghezza della stringa all'indirizzo iniziale della stringa ANSI. Poiché il puntatore stringa non gestito punta ora alla fine della stringa, l'operazione di copia copia copiarà un carattere dalla fine della stringa all'inizio del blocco di memoria.

  4. Usa un ciclo per copiare ogni carattere dalla stringa al blocco di memoria non gestito.

    Nell'esempio Visual Basic viene chiamato il metodo Marshal.ReadByte(IntPtr, Int32) per leggere il byte (o un carattere a un byte) in corrispondenza di un offset specificato dal puntatore gestito alla stringa ANSI. L'offset viene incrementato con ogni iterazione del ciclo. Chiama quindi il Marshal.WriteByte(IntPtr, Int32, Byte) metodo per scrivere il byte nell'indirizzo di memoria definito dall'indirizzo iniziale del blocco di memoria non gestito più offset. Quindi decrementa offset.

    Gli esempi C#, F# e C++ eseguono l'operazione di copia, quindi decrementare il puntatore all'indirizzo della posizione successiva nella stringa ANSI non gestita e incrementare il puntatore all'indirizzo successivo nel blocco non gestito.

  5. Tutti gli esempi chiamano per Marshal.PtrToStringAnsi convertire il blocco di memoria non gestito contenente la stringa ANSI copiata in un oggetto Unicode String gestito.

  6. Dopo aver visualizzato le stringhe originali e invertite, tutti gli esempi chiamano il FreeHGlobal metodo per liberare la memoria allocata per la stringa ANSI non gestita e il blocco di memoria non gestito.

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

Commenti

Il IntPtr tipo è progettato per essere un numero intero la cui dimensione è uguale a un puntatore. Ovvero, un'istanza di questo tipo dovrebbe essere a 32 bit in un processo a 32 bit e 64 bit in un processo a 64 bit.

Il IntPtr tipo può essere usato dalle lingue che supportano puntatori e come mezzo comune per fare riferimento ai dati tra lingue che e non supportano i puntatori.

IntPtr gli oggetti possono essere utilizzati anche per contenere handle. Ad esempio, le istanze di IntPtr vengono usate ampiamente nella System.IO.FileStream classe per contenere handle di file.

Note

L'uso IntPtr di come puntatore o handle è soggetto a errori e non sicuro. Si tratta semplicemente di un tipo integer che può essere usato come formato di interscambio per puntatori e handle a causa della stessa dimensione. Al di fuori di specifici requisiti di interscambio, ad esempio per il passaggio di dati a una lingua che non supporta i puntatori, è consigliabile usare un puntatore tipizzato correttamente per rappresentare i puntatori e SafeHandle usare per rappresentare gli handle.

Questo tipo implementa .ISerializable In .NET 5 e versioni successive, questo tipo implementa anche le interfacce IFormattable. In .NET 7 e versioni successive, questo tipo implementa anche le interfacce IBinaryInteger<TSelf>, IMinMaxValue<TSelf> e ISignedNumber<TSelf>.

In C# a partire dalla versione 9.0 è possibile usare il tipo predefinito nint per definire numeri interi di dimensioni native. Questo tipo è rappresentato dal IntPtr tipo internamente e fornisce operazioni e conversioni appropriate per i tipi integer. Per altre informazioni, vedere tipi nint e nuint.

In C# a partire dalla versione 11 e quando la destinazione è il runtime di .NET 7 o versione successiva, nint è un alias per IntPtr nello stesso modo in cui int è un alias per Int32.

Costruttori

Nome Descrizione
IntPtr(Int32)

Inizializza una nuova istanza di IntPtr utilizzando l'intero con segno a 32 bit specificato.

IntPtr(Int64)

Inizializza una nuova istanza di IntPtr utilizzando l'intero con segno a 64 bit specificato.

IntPtr(Void*)

Inizializza una nuova istanza di IntPtr utilizzando il puntatore specificato a un tipo non specificato.

Campi

Nome Descrizione
Zero

Campo di sola lettura che rappresenta un intero con segno inizializzato su zero.

Proprietà

Nome Descrizione
Size

Ottiene le dimensioni di questa istanza.

Metodi

Nome Descrizione
Add(IntPtr, Int32)

Aggiunge un offset a un intero con segno.

Equals(Object)

Restituisce un valore che indica se questa istanza è uguale a un oggetto specificato.

GetHashCode()

Restituisce il codice hash per questa istanza.

Subtract(IntPtr, Int32)

Sottrae un offset da un intero con segno.

ToInt32()

Converte il valore di questa istanza in un intero con segno a 32 bit.

ToInt64()

Converte il valore di questa istanza in un intero con segno a 64 bit.

ToPointer()

Converte il valore di questa istanza in un puntatore a un tipo non specificato.

ToString()

Converte il valore numerico dell'oggetto corrente IntPtr nella rappresentazione di stringa equivalente.

ToString(String)

Converte il valore numerico dell'oggetto corrente IntPtr nella rappresentazione di stringa equivalente.

Operatori

Nome Descrizione
Addition(IntPtr, Int32)

Aggiunge un offset a un intero con segno.

Equality(IntPtr, IntPtr)

Determina se due istanze specificate di IntPtr sono uguali.

Explicit(Int32 to IntPtr)

Converte il valore di un intero con segno a 32 bit in un oggetto IntPtr.

Explicit(Int64 to IntPtr)

Converte il valore di un intero con segno a 64 bit in un oggetto IntPtr.

Explicit(IntPtr to Int32)

Converte il valore dell'oggetto specificato IntPtr in un intero con segno a 32 bit.

Explicit(IntPtr to Int64)

Converte il valore dell'oggetto specificato IntPtr in un intero con segno a 64 bit.

Explicit(IntPtr to Void*)

Converte il valore dell'oggetto specificato IntPtr in un puntatore a un tipo non specificato.

Questa API non è conforme a CLS.

Explicit(Void* to IntPtr)

Converte il puntatore specificato in un tipo non specificato in un oggetto IntPtr.

Questa API non è conforme a CLS.

Inequality(IntPtr, IntPtr)

Determina se due istanze specificate di IntPtr non sono uguali.

Subtraction(IntPtr, Int32)

Sottrae un offset da un intero con segno.

Implementazioni dell'interfaccia esplicita

Nome Descrizione
IEquatable<IntPtr>.Equals(IntPtr)

Restituisce un valore che indica se questa istanza è uguale a un altro intero con segno.

ISerializable.GetObjectData(SerializationInfo, StreamingContext)

Popola un SerializationInfo oggetto con i dati necessari per serializzare l'oggetto corrente IntPtr .

Si applica a

Thread safety

Questo tipo è thread-safe.

Vedi anche