in C#, c'è un modo perC e variabile
- Indirizzo memorizzato in una variabile di tipo di riferimento?
- Ottieni l'indirizzo di memoria di una variabile ?
EDIT:
int i;
int* pi = &i;
- Come si fa a stampare il valore esadecimale di pi greco?
in C#, c'è un modo perC e variabile
EDIT:
int i;
int* pi = &i;
Per 2 #, l'operatore &
funzionerà nello stesso modo come in C. Se la variabile non è in pila, potrebbe essere necessario utilizzare un'istruzione fixed
al pin giù mentre si lavora così la spazzatura il collezionista non lo muove, però.
Per il numero 1, i tipi di riferimento sono più complicati: è necessario utilizzare uno GCHandle
e il tipo di riferimento deve essere blittabile, ovvero avere un layout di memoria definito ed essere copiabile per bit.
Per poter accedere l'indirizzo come un numero, è possibile trasmettere da tipo puntatore a IntPtr
(un tipo intero definito come la stessa dimensione come un puntatore), e da lì a uint
o ulong
(a seconda della dimensione del puntatore della macchina sottostante).
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
class Blittable
{
int x;
}
class Program
{
public static unsafe void Main()
{
int i;
object o = new Blittable();
int* ptr = &i;
IntPtr addr = (IntPtr)ptr;
Console.WriteLine(addr.ToString("x"));
GCHandle h = GCHandle.Alloc(o, GCHandleType.Pinned);
addr = h.AddrOfPinnedObject();
Console.WriteLine(addr.ToString("x"));
h.Free();
}
}
Il numero 1 non è possibile, non è possibile avere un puntatore a un oggetto gestito. Tuttavia, è possibile utilizzare una struttura IntPtr per ottenere informazioni circa l'indirizzo del puntatore nel riferimento:
GCHandle handle = GCHandle.Alloc(str, GCHandleType.Pinned);
IntPtr pointer = GCHandle.ToIntPtr(handle);
string pointerDisplay = pointer.ToString();
handle.Free();
Per il numero 2 si utilizza il & dell'operatore:
int* p = &myIntVariable;
Puntatori ovviamente devono essere fatto in un blocco non sicuro, e devi consentire il codice non sicuro nelle impostazioni del progetto. Se la variabile è una variabile locale in un metodo, viene allocata nello stack in modo che sia già fissa, ma se la variabile è un membro di un oggetto, devi mettere quell'oggetto in memoria usando la parola chiave fixed
in modo che non venga spostato da il netturbino.
Weired, perché il codice non può essere compilato con string str =" hello "; string * ptr = str;? qualsiasi idea? –
Il mio male, che in realtà non è possibile a tutti. non può avere un puntatore a un oggetto gestito, devi usare un IntPtr. – Guffa
Perché il downvote? Se non dici quello che non ti piace, è piuttosto inutile ... – Guffa
Per rispondere alla tua domanda più correttamente:
# 1 è possibile, ma un po 'complicato, e dovrebbe essere fatto solo per motivi di debug:
object o = new object();
TypedReference tr = __makeref(o);
IntPtr ptr = **(IntPtr**)(&tr);
Questo funziona per qualsiasi oggetto e in realtà restituisce l'interno puntatore all'oggetto in memoria. Ricorda che l'indirizzo può cambiare in qualsiasi momento a causa del GC, che ama spostare gli oggetti attraverso la memoria.
# 2 I puntatori non sono oggetti e pertanto non ereditano da ToString. Bisogna lanciare il puntatore IntPtr in questo modo:
Console.WriteLine((IntPtr)pi);
# 2, che è cool. ma come si può ottenere l'indirizzo di memoria come una stringa. dì int i; int * pi = & i; Non riesco a stamparlo usando la Console.WriteLine (PI); Mi aspetto che qualcosa come 0x0439ecc4 sia stampato. Qualche indizio? –
Console.WriteLine ("0x" + pi.ToString ("x") stampa il valore esadecimale –
@Hamish, pi.ToString ("x") genera errore di compilazione. "Operatore '.' Non può essere applicato all'operando di tipo 'int *' " –