Qué es [DllImport ("QCall")]?


Muchos métodos en la biblioteca.Net están implementados en código nativo. Los que provienen del propio framework están marcados con [MethodImpl(MethodImplOptions.InternalCall)]. Aquellos que provienen de alguna DLL no administrada están marcados con [DllImport] (por ejemplo, [DllImport("kernel32.dll")]). Hasta ahora nada inusual.

Pero mientras escribía respuesta para otra pregunta, descubrí que hay muchos métodos marcados con [DllImport("QCall")]. Parecen ser una implementación interna de. Net (por ejemplo, GC._Collect()).

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

Author: Community, 2012-02-29

3 answers

Este es un hilo antiguo. Dado que CoreCLR ahora es de código abierto en GitHub; si alguien todavía está buscando la respuesta, aquí está la documentación oficial:

Llamando desde el código gestionado al nativo

Tenemos dos técnicas para llamar al CLR desde 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 agujeros GC al no rastrear referencias de objetos correctamente. QCall le permite llamar al CLR a través del P/Invoke, y es mucho más difícil de usar accidentalmente que FCall. Las FCalls se identifican en código administrado como métodos externos con MethodImplOptions.Bit de llamada interna establecido. QCalls son métodos externos estáticos que se parecen a P/Invokes regulares, pero a una biblioteca llamada "QCall".

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

Y luego continúa en subtítulos:

Con ejemplos:

 14
Author: vulcan raven,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-25 03:20:28

Le pregunté a algunas personas en el equipo de.Net sobre esto.

QCalls son llamadas a métodos nativos dentro del tiempo de ejecución de CLR. Se comportan como otros [DllImport], 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 varias comprobaciones de marshalling y GC y exception.

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

 35
Author: SLaks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-01 20:18:57

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

Básicamente, InternalCall le dice al tiempo de ejecución que vaya a revisar su propia tabla de búsqueda interna de funciones con nombre. 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 implementar 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 Guid administrado.El método CompleteGuid es en realidad la función GuidNative::CompleteGuid nativa de C++. El artículo no es muy claro sobre cómo funciona el marshaling 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 marshaling] y b) hace cualquier marshal requerido.

 0
Author: Tim Lovell-Smith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-10 20:50:09