当使用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的代码?
你需要的源代码,CLR看到这些方法的实现。 这是一个有点来之不易,微软并没有公布它,它是不包括在参考源。
只要方法是“老”,可因为.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有着怎样的方法名称作为一个字符串和一个函数指针,以实现内部通话的C ++方法。 Grepping源代码树,然后把你带到CLR / src目录/ VM / comstring.cpp。 我暂且不谈大家与C ++代码,只要看看自己。
/*================================CompareOrdinal===============================*/
FCIMPL3(INT32, COMString::FCCompareOrdinal, StringObject* strA, StringObject* strB, CLR_BOOL bIgnoreCase) {
// Yadayada
//...
}
搜索CaseInsensitiveCompHelper()和FastCompareStringHelperAligned()需要你的,分别为不区分大小写和区分大小写的比较功能在相同的源代码文件中的实际的实现方式。
值得注意的这个唯一的另一件事是,CLR版本4做了一些修改这一机制。 添加大量的新的内部的方法和通过名为“QCall”假DLL一个函数[DllImport]属性支持一个完全不同的附加的互操作的机制。 有看到源这些加法,我知道没有什么好办法。
UPDATE:来源是现在可以从CoreCLR项目 。 该表是从ecall.cpp搬到ecalllist.h,技工仍然是相同的。 请记住,这是CLR的.NETCore版,桌面版源仍然是闭源。 这两个版本都不过可能有很多共同点。
由于现在CoreCLR是开源的 ,这样我们就可以检查出的内部代码。
你可以搜索COMString::CompareOrdinalEx
关键字stringnative.cpp看到内部实现。
作为帮助串说,他们是“在CLR本身实现的”,所以你需要咨询的C ++源代码或拆卸。
一般来说,包括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
由备份CLRRuntimeInfoImpl
COM类在mscoreei.dll
,方法简单地是其虚函数。