2012-02-28 10 views
61

Muchos métodos en la biblioteca .Net se implementan en código nativo. Los que provienen del propio marco están marcados con [MethodImpl(MethodImplOptions.InternalCall)]. Los que provienen de algún DLL no administrado están marcados con [DllImport] (por ejemplo, [DllImport("kernel32.dll")]). Hasta ahora nada inusual¿Qué es [DllImport ("QCall")]?

Pero al escribir answer for another question, descubrí que hay muchos métodos marcados con [DllImport("QCall")]. Parecen ser implementaciones internas de .Net (por ejemplo, GC._Collect()).

Mi pregunta es: ¿Qué significa exactamente [DllImport("QCall")]? ¿Cuál es la diferencia entre [DllImport("QCall")] y [MethodImpl(MethodImplOptions.InternalCall)]?

+1

Es una llamada interna especial; Estoy tratando de encontrar detalles. – SLaks

+0

Recuerdo haber leído un rato que "QCall" es parte de clr.dll. Yo, sin embargo, no sé mucho más que eso. +1 para una excelente pregunta. – ahawker

+11

Es una característica específica de .NET 4. Puede obtener un poco de información de la fuente de referencia V4, consulte el código fuente de System.Runtime.CompilerServices.Jithelpers.cs. La cadena aparece dos veces en clr.dll, como __IsQCall y como un literal en línea. Esto se asemeja mucho a un mecanismo de extensión más allá de MethodImplOptions.InternalCall, demostrando que es difícil sin el código fuente de CLR. –

Respuesta

14

Esto es un hilo viejo. Dado que CoreCLR ahora tiene un código abierto en GitHub; si alguien todavía está buscando la respuesta, aquí está el official documentation:

Calling from managed to native code

Tenemos dos técnicas para poner en el CLR de código administrado. FCall le permite llamar directamente al código CLR, y proporciona mucha flexibilidad en términos de manipulación de objetos, aunque es fácil causar huecos GC al no rastrear referencias de objetos correctamente. QCall le permite llamar al CLR a través de la P/Invoke, y es mucho más difícil de utilizar accidentalmente que FCall. FCalls se identifican en código administrado como métodos externos con el conjunto de bits MethodImplOptions.InternalCall. QCalls son métodos externos estáticos que parecen P/Invocaciones regulares, pero a una biblioteca llamada "QCall".

Hay una pequeña variante de FCall llamada HCall (para llamada auxiliar) para implementar JIT helpers, para hacer cosas como acceder a elementos de matriz multidimensionales, verificaciones de rango, etc. La única diferencia entre HCall y FCall es que los métodos de HCall no se mostrará en un seguimiento de pila de excepción.

Y luego se continúa en las subpartidas:

con ejemplos:

35

Le pregunté a algunas personas del equipo .Net sobre esto.

QLas llamadas son llamadas a métodos nativos dentro del tiempo de ejecución de CLR. Se comportan como otros [DllImport] s, pero son más rápidos porque hacen suposiciones específicas (no documentadas) sobre lo que hacen los métodos nativos, por lo que pueden omitir varios controles de clasificación y GC y excepciones.

InternalCall es diferente; es para las llamadas a cosas especiales del estilo de reflexión que se generan en el tiempo de ejecución (esto no era muy claro).

0

Suplementando @SLaks respuesta, MethodImplOptions.InternalCall se describe brevemente aquí: ThreadPoolPriority, and MethodImplAttribute.

Básicamente, InternalCall le dice al motor de ejecución que compruebe su propia tabla de búsqueda interna de funciones nombradas. Esa tabla existe debido a un archivo fuente en el código de tiempo de ejecución que los declara explícitamente cuando se compila el tiempo de ejecución. Tiene una lista de punteros de función para la implementación de todas las llamadas internas:

static ECFunc gGuidFuncs[] = { {FCFuncElement("CompleteGuid", NULL, (LPVOID)GuidNative::CompleteGuid)}, {NULL, NULL, NULL} }; 

Esta declaración indica al tiempo de ejecución que el cuerpo del método para el método Guid.CompleteGuid administrado es en realidad el C++ :: GuidNative función CompleteGuid nativa. El artículo no es muy claro sobre cómo funcionan las referencias en este lugar, pero en general eso depende claramente de la implementación en tiempo de ejecución, ya que a) declara el cuerpo de la función [que depende del formato de clasificación] yb) hace referencia a cualquier ordenamiento .

Cuestiones relacionadas