domanda semplice, importare una funzione DLL e il parametro sono int *. Quando provo ad inserire Method (0), viene visualizzato un errore che dice: "int e int * non può convertire".DotNet - Che cosa è int *?
Che cosa significa?
domanda semplice, importare una funzione DLL e il parametro sono int *. Quando provo ad inserire Method (0), viene visualizzato un errore che dice: "int e int * non può convertire".DotNet - Che cosa è int *?
Che cosa significa?
Questa è la notazione C classica per un pointer to an int
. Ogni volta che un tipo è seguito da un *
, indica quel tipo come pointer per quel tipo. In C#, a differenza di C, è necessario definire esplicitamente funzioni come unsafe
per utilizzare i puntatori, oltre a abilitare il codice unsafe nelle proprietà del progetto. Anche un tipo di puntatore non è direttamente intercambiabile con un tipo concreto, quindi il riferimento di un tipo deve essere preso per primo. Per ottenere un puntatore a un altro tipo, ad esempio un int, in C# (o C & C++), è necessario utilizzare l'operatore di dereferenza &
(e commerciale) davanti alla variabile a cui si desidera ottenere un puntatore:
unsafe
{
int i = 5;
int* p = &i;
// Invoke with pointer to i
Method(p);
}
codice 'non sicuro' C#
seguito sono riportati alcuni articoli chiave su codice non sicuro e l'uso di puntatori in C#.
È un pointer to an int. Generalmente meglio evitato nel codice gestito. È possibile che si desideri pubblicare la dichiarazione del metodo importata. Un IntPtr è di solito sufficiente per questo tipo di interoperabilità.
È solo un argomento passato per riferimento. È ben supportato dal marshaller P/Invoke, l'utilizzo di IntPtr è un errore. –
Dipende da cosa fa. Se è un array, 'int []' è quello che vuoi. Se è un handle, 'IntPtr' di solito è il migliore, specialmente se si pianifica di passare 0. Se si desidera un riferimento effettivo a un int,' ref int' o 'out int' potrebbe funzionare meglio. – Blindy
Senza vedere la dichiarazione del metodo non sarei in grado di indovinare in un modo o nell'altro (ref vs array vs pointer). @Blindy ha ragione sui soldi. Dipende dal metodo che viene chiamato. Il LPARAM di SendMessage, per esempio, è solitamente configurato come IntPtr e quel tipo in genere possiede un puntatore di memoria (che può essere espresso come int *) – dkackman
Dipende dalla lingua utilizzata. In C#, dovresti dichiarare l'argomento con la parola chiave "ref". In VB.NET dovresti usare la parola chiave ByRef. E devi chiamarlo passando una variabile, non una costante. Qualcosa del genere:
int retval = 0;
Method(ref retval);
// Do something with retval
//...
È praticamente uguale al & usato nella risposta accettata? –
Sotto il cappuccio dopo che il jitter è finito, sì. –
Se gli autori della DLL che ha usato decidono il metodo di firma # C# (int * p) ', allora non può invocare il metodo con la sintassi' Metodo (ref retval); 'proponi, giusto? Gli autori della DLL _could_ hanno scelto invece un metodo 'Method (ref int p)', ma per qualche motivo non l'hanno fatto. C# non offre "aritmetica" su variabili di tipo "ref int", come l'incremento per l'indirizzo "next", il modo in cui funziona con i puntatori "int * p" (come C# "p ++" e altri "non sicuri") . –
Per aggiungere qui, '&' è ottenere il puntatore (indirizzo) di' int i' ... – Nate
@Nate: buon punto, aggiungerò una spiegazione migliore dell'operatore di dereferenziazione. – jrista
Stesso commento qui: non ha nulla a che fare con il codice non sicuro. L'argomento è semplicemente passato per riferimento. La parola chiave "ref" in C#. È anche un puntatore in C# nel momento in cui il compilatore JIT ha finito. –