Что такое [DllImport ("QCall")]? - PullRequest
       17

Что такое [DllImport ("QCall")]?

65 голосов
/ 29 февраля 2012

Многие методы в библиотеке .Net реализованы в собственном коде. Те, которые приходят из самого фреймворка, помечены [MethodImpl(MethodImplOptions.InternalCall)]. Те, которые приходят из какой-то неуправляемой библиотеки DLL, помечены [DllImport] (например, [DllImport("kernel32.dll")]). Пока ничего необычного.

Но при написании ответа на другой вопрос я обнаружил, что есть много методов, помеченных [DllImport("QCall")]. Кажется, они являются внутренней реализацией .Net (например, GC._Collect()).

Мой вопрос: что именно означает [DllImport("QCall")]? В чем разница между [DllImport("QCall")] и [MethodImpl(MethodImplOptions.InternalCall)]?

Ответы [ 3 ]

35 голосов
/ 01 марта 2012

Я спросил некоторых людей из команды .Net об этом.

QCalls - это вызовы нативных методов в среде CLR.Они ведут себя как другие [DllImport] с, но они быстрее, потому что они делают определенные (недокументированные) предположения о том, что делают нативные методы, поэтому они могут пропускать различные проверки и GC и проверки исключений.

InternalCallэто отличается;это для вызовов специальных вещей в стиле отражения, которые генерируются во время выполнения (это было не очень понятно).

16 голосов
/ 25 мая 2015

Это старая ветка. Поскольку CoreCLR теперь с открытым исходным кодом на GitHub; если кто-то все еще ищет ответ, вот официальная документация :

Звонок с управляемого на собственный код

У нас есть два метода вызова CLR из управляемого кода. FCall позволяет вам напрямую вызывать код CLR и обеспечивает большую гибкость в плане манипулирования объектами, хотя легко вызвать дыры в GC, если не правильно отслеживать ссылки на объекты. QCall позволяет вам звонить в CLR через P / Invoke, и случайное неправильное использование намного сложнее, чем FCall. FCall идентифицируются в управляемом коде как внешние методы с установленным битом MethodImplOptions.InternalCall. QCalls - это статические методы extern, которые выглядят как обычные P / Invokes, но для библиотеки с именем "QCall".

Существует небольшой вариант FCall, называемый HCall (для вызова Helper), для реализации помощников JIT, для таких вещей, как доступ к элементам многомерного массива, проверка диапазона и т. Д. Единственное отличие между HCall и FCall состоит в том, что методы HCall победили. в трассировке стека исключений.

А затем он продолжается в подзаголовках:

с примерами:

0 голосов
/ 10 декабря 2013

В дополнение к ответу @SLaks, MethodImplOptions.InternalCall кратко описан здесь: ThreadPoolPriority и MethodImplAttribute .

По сути, InternalCall сообщает среде выполнения о необходимости проверки своих внутреннихтаблица поиска именованных функций.Эта таблица существует из-за исходного файла в коде среды выполнения, явно объявившего их при компиляции среды выполнения.В нем есть список указателей на функции для реализации всех внутренних вызовов:

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

Это объявление сообщает среде выполнения, что тело метода для управляемого метода Guid.CompleteGuid на самом деле является родной функцией C ++ GuidNative :: CompleteGuid.В статье не очень ясно, как маршалинг работает в этом месте, но в целом это явно зависит от реализации во время выполнения, так как он а) объявляет тело функции [которое зависит от формата маршалинга] и б) выполняет необходимое маршалинг.

...