Ответ 1
С тех пор CoreCLR является открытым исходным кодом, поэтому мы можем проверить внутренний код.
Вы можете найти ключевое слово COMString::CompareOrdinalEx
в stringnative.cpp, чтобы увидеть внутреннюю реализацию.
Когда вы используете ILSpy для проверки кода System.String, я обнаружил, что есть некоторые методы, помеченные как MethodImplOptions.InternalCall, такие как:
[SecurityCritical]
[MethodImpl(MethodImplOptions.InternalCall)]
internal static extern int nativeCompareOrdinalEx(string strA, int indexA, string strB, int indexB, int count);
Я знаю MethodImplOptions. InternalCall означает, что этот метод реализован изначально с помощью среды выполнения общего языка для оптимизации кода для повышения производительности.
Мой вопрос: это так или иначе может позволить нам увидеть код, помеченный как MethodImplOptions.InternalCall?
С тех пор CoreCLR является открытым исходным кодом, поэтому мы можем проверить внутренний код.
Вы можете найти ключевое слово COMString::CompareOrdinalEx
в stringnative.cpp, чтобы увидеть внутреннюю реализацию.
Вам понадобится исходный код для CLR, чтобы увидеть реализацию этих методов. Это немного сложно, Microsoft не публикует его, и он не охвачен справочным источником.
Пока этот метод является "старым", доступным с .NET 2.0, вы можете сделать снимок с исходный код SSCLI20. С ненулевым риском вы, конечно, будете смотреть на устаревшую версию кода. Но достаточно хорошо, чтобы понять, как это выглядит и часто все еще точным.
Отправной точкой для начала поиска кода является файл исходного кода clr/src/vm/ecall.cpp. Он содержит таблицы, в которых джиттер ищет внутренние методы. Раздел, относящийся к nativeCompareOrdinalEx(), выглядит следующим образом:
FCFuncStart(gStringFuncs)
FCDynamic("FastAllocateString", CORINFO_INTRINSIC_Illegal, ECall::FastAllocateString)
FCDynamicSig(COR_CTOR_METHOD_NAME, &gsig_IM_ArrChar_RetVoid, CORINFO_INTRINSIC_Illegal, ECall::CtorCharArrayManaged)
FCDynamicSig(COR_CTOR_METHOD_NAME, &gsig_IM_ArrChar_Int_Int_RetVoid, CORINFO_INTRINSIC_Illegal, ECall::CtorCharArrayStartLengthManaged)
FCDynamicSig(COR_CTOR_METHOD_NAME, &gsig_IM_PtrChar_RetVoid, CORINFO_INTRINSIC_Illegal, ECall::CtorCharPtrManaged)
FCDynamicSig(COR_CTOR_METHOD_NAME, &gsig_IM_PtrChar_Int_Int_RetVoid, CORINFO_INTRINSIC_Illegal, ECall::CtorCharPtrStartLengthManaged)
FCDynamicSig(COR_CTOR_METHOD_NAME, &gsig_IM_Char_Int_RetVoid, CORINFO_INTRINSIC_Illegal, ECall::CtorCharCountManaged)
FCFuncElement("nativeCompareOrdinal", COMString::FCCompareOrdinal) // <=== Here
FCFuncElement("nativeCompareOrdinalWC", COMString::FCCompareOrdinalWC)
FCIntrinsic("get_Length", COMString::Length, CORINFO_INTRINSIC_StringLength)
// etc..
}
Обратите внимание, как FCFuncElement имеет имя метода как строку и указатель на метод С++, который реализует внутренний вызов. Грепирование дерева исходного кода приведет вас к clr/src/vm/comstring.cpp. Я не буду утомлять всех кодом С++, просто взгляните на себя.
/*================================CompareOrdinal===============================*/
FCIMPL3(INT32, COMString::FCCompareOrdinal, StringObject* strA, StringObject* strB, CLR_BOOL bIgnoreCase) {
// Yadayada
//...
}
Поиск CaseInsensitiveCompHelper() и FastCompareStringHelperAligned() возвращает вас к фактическим реализациям несовместимых с регистром и чувствительных к регистру функций сравнения в том же файле исходного кода.
Единственное, что примечательно, это то, что версия CLR 4 внесла некоторые изменения в этот механизм. Добавление множества новых внутренних методов и поддержка совершенно другого дополнительного механизма взаимодействия с помощью атрибута [DllImport] для поддельной DLL с именем "QCall". Там нет хорошего способа увидеть источник этих дополнений, о которых я знаю.
UPDATE: источник теперь доступен из проекта CoreCLR. Таблица была перенесена с ecall.cpp на ecalllist.h, механики все те же. Имейте в виду, что это версия .NETCore для CLR, источник настольной версии по-прежнему закрыт. Однако две версии имеют много общего.
Как говорится в строке справки, они "реализованы в самой CLR", поэтому вам нужно проконсультироваться со своими источниками или дизассемблированием на С++.
Обычно файлы, которые содержат механизм CLR, представляют собой несколько встроенных DLL файлов в папке %WINDIR%\Microsoft.NET\Framework\<.NET engine version>
, в основном mscor*.dll
и clr.dll
. Корневая .NET DLL, mscoree.dll
, находится в System32
, но кажется, что она действует только как запускающая программа.
Поскольку реализации метода InternalCall
являются деталями реализации, нет гарантии, что эти методы будут реализованы согласованным образом, например. что там даже какой-то глобальный реестр.
например. дизассемблирование показывает, что встроенные методы .NET 4 System.String
реализованы в clr.dll
и указаны в структуре, подобной каталогу, а System.Deployment.Application.NativeMethods.IClrRuntimeInfo
поддерживается классом COM CLRRuntimeInfoImpl
в mscoreei.dll
, причем методы просто являются его виртуальными функциями.