2010-07-13 13 views
12

pregunta simple, importo una función DLL y el parámetro es int *. Cuando intento ingresar al Método (0), aparece un error que dice: "int e int * no se puede convertir".DotNet - ¿Qué es int *?

¿Qué significa eso?

Respuesta

15

Esa es la notación C clásica para un pointer to an int. Cuando un tipo es seguido por un *, denota ese tipo como pointer a ese tipo. En C#, a diferencia de C, debe definir explícitamente funciones como unsafe para usar punteros, además de habilitar el código unsafe en las propiedades de su proyecto. Un tipo de puntero tampoco es directamente intercambiable con un tipo concreto, por lo que la referencia de un tipo debe tomarse primero. Para obtener un puntero a otro tipo, como int, en C# (o C & C++ para el caso), debe usar el operador de referencia & (ampersand) delante de la variable a la que desea obtener un puntero:

unsafe 
{ 
    int i = 5; 
    int* p = &i; 
    // Invoke with pointer to i 
    Method(p); 
} 

código 'inseguro' C#

a continuación se presentan algunos artículos clave de código no seguro y el uso de punteros en C#.

+0

Para agregar aquí, '&' es para obtener el puntero (dirección) de 'int i' ... – Nate

+0

@Nate: Buen punto, añadiré una mejor explicación del operador de desreferencia. – jrista

+0

Mismo comentario aquí: no tiene nada que ver con el código inseguro. El argumento simplemente se pasa por referencia. La palabra clave "ref" en C#. También es un puntero en C# cuando el compilador JIT termina con él. –

6

Es un pointer to an int. Generalmente es mejor evitarlo en código administrado. Es posible que desee publicar su declaración de método importado. Un IntPtr suele ser suficiente para este tipo de interoperabilidad.

+1

Es solo un argumento que se pasa por referencia. Es bien soportado por el Marshaller P/Invoke, el uso de IntPtr es un error. –

+2

Depende de lo que haga. Si es una matriz, 'int []' es lo que quieres. Si es un identificador, 'IntPtr' por lo general es mejor, especialmente si planea pasar 0. Si desea una referencia real a un int,' ref int' o 'out int' podría funcionar mejor. – Blindy

+1

Sin ver la declaración del método, no podría adivinar de una forma u otra (ref vs array versus puntero). @Blindy tiene razón con el dinero. Depende del método que se llame. La LPARAM de SendMessage, por ejemplo, generalmente se organiza como IntPtr y ese tipo suele contener un puntero de memoria (que puede expresarse como int *) – dkackman

2

Depende del idioma que utilice. En C#, debe declarar el argumento con la palabra clave "ref". En VB.NET debe usar la palabra clave ByRef. Y necesita llamar pasando una variable, no una constante. Algo como esto:

int retval = 0; 
Method(ref retval); 
// Do something with retval 
//... 
+0

¿Es la referencia prácticamente la misma que la & usada en la respuesta aceptada? –

+0

Debajo del capó después de que la trepidación haya terminado, sí. –

+0

Si los autores de la DLL que utilizó decidieron en la firma C# 'Método (int * p)', entonces no puede invocar el método con la sintaxis 'Método (ref retval);' usted propone, ¿verdad? Los autores de la DLL _deberían haber elegido una firma 'Método (ref int p)' en su lugar, pero por alguna razón no lo hicieron. C# no ofrece "aritmética" en variables del tipo 'ref int', como el incremento en la" siguiente "dirección, de la forma en que lo hace con los punteros' int * p' (como C# 'p ++' y otros, "inseguro") . –