.net dllimport internals

.net - ¿Qué es[DllImport("QCall")]?



internals (3)

Complementando la respuesta de @SLaks, MethodImplOptions.InternalCall se describe brevemente aquí: ThreadPoolPriority y MethodImplAttribute .

Básicamente, InternalCall le dice al tiempo 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 implementar todas las llamadas internas:

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

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

Muchos métodos en la biblioteca .Net se implementan en código nativo. Los que provienen del marco mismo están marcados con [MethodImpl(MethodImplOptions.InternalCall)] . Los 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 la respuesta para otra pregunta , descubrí que hay muchos métodos marcados con [DllImport("QCall")] . Parecen ser implementación interna 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)] ?


Este es un viejo hilo. 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 :

Llamar desde código administrado a código 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 en el GC al no rastrear las referencias de los objetos correctamente. QCall le permite llamar al CLR a través de P / Invoke, y es mucho más difícil de mal uso accidental que FCall. Los FCalls se identifican en el código administrado como métodos externos con el conjunto de bits MethodImplOptions.InternalCall. QCalls son métodos externos estáticos que se parecen a P / Invokes normales, 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 elementos de matrices multidimensionales, verificaciones de rango, etc. La única diferencia entre HCall y FCall es que los métodos de HCall no se mostrarán. arriba en un seguimiento de pila de excepción.

Y luego continúa en los subtítulos:

con ejemplos:


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] 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 de excepciones.

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