Что такое [DllImport ("QCall")]?
многие методы в библиотеке .Net реализованы в машинном коде. Те, которые исходят из самой структуры, отмечены [MethodImpl(MethodImplOptions.InternalCall)]. Те, которые приходят из некоторых неуправляемых DLL помечены [DllImport] (например,[DllImport("kernel32.dll")]). Пока ничего необычного.
но при написании ответа на другой вопрос, я обнаружил, что есть много методов, отмеченных [DllImport("QCall")]. Они кажутся внутренней реализацией .Net (например,GC._Collect()).
мой вопрос: что именно делает [DllImport("QCall")] в смысле? В чем разница между [DllImport("QCall")] и [MethodImpl(MethodImplOptions.InternalCall)]?
3 ответов:
Это старый поток. Поскольку CoreCLR теперь открыт с открытым исходным кодом на GitHub; если кто-то все еще ищет ответ, вот официальная документация:
звонок из управляемого в машинный код
У нас есть два метода для вызова CLR из управляемого кода. FCall позволяет вам вызывать непосредственно в код CLR и обеспечивает большую гибкость с точки зрения манипулирования объектами, хотя легко вызвать отверстия GC с помощью неправильное отслеживание ссылок на объекты. QCall позволяет вам вызывать CLR через P / Invoke, и гораздо сложнее случайно неправильно использовать, чем FCall. FCalls идентифицируются в управляемом коде как extern методы с MethodImplOptions.InternalCall бит. QCalls-это статические методы extern, которые выглядят как обычные P / Invokes, но в библиотеку под названием "QCall".
существует небольшой вариант FCall под названием HCall (для вызова помощника) для реализации помощников JIT, для выполнения таких вещей, как доступ к многомерной элементов массива, диапазон проверки, и т. д. Единственное различие между hcall и FCall заключается в том, что методы HCall не будут отображаться в трассировке стека исключений.
и затем он продолжается в подзаголовках:
примеры:
Я спросил об этом некоторых людей в команде .Net.
QCalls-это вызовы собственных методов во время выполнения среды CLR. Они ведут себя как другие
[DllImport]s, но они быстрее, потому что они делают определенные (недокументированные) предположения о том, что делают собственные методы, поэтому они могут пропустить различные маршалинг и проверки GC и исключений.
InternalCallдругое; это требует особого осмысления вещей, которые генерируются во время выполнения (это не очень четкий.)
дополнение @SLaks ответ, MethodImplOptions.InternalCall кратко описывается здесь:ThreadPoolPriority и MethodImplAttribute.
в основном InternalCall говорит среде выполнения, чтобы пойти проверить свою собственную внутреннюю таблицу поиска именованных функций. Эта таблица существует из-за исходного файла в коде среды выполнения, явно объявляющего их при компиляции среды выполнения. Он имеет список указателей функций для реализации всех внутренних звонки:
static ECFunc gGuidFuncs[] = { {FCFuncElement("CompleteGuid", NULL, (LPVOID)GuidNative::CompleteGuid)}, {NULL, NULL, NULL} };это объявление сообщает среде выполнения, что тело метода для управляемого Guid.Метод CompleteGuid на самом деле является собственной функцией C++ GuidNative::CompleteGuid. В статье не очень ясно, как работает маршалинг в этом месте, но в целом это явно зависит от реализации среды выполнения, поскольку она а) объявляет тело функции [которое зависит от формата маршалинга] и Б) выполняет любой требуемый маршалинг.
Comments