c# - 如何查看标记为 MethodImplOptions.InternalCall 的方法代码?

标签 c# .net clr

在使用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 意味着此方法由公共(public)语言运行时 native 实现以优化代码以提高性能。

我的问题是:不管怎样,这是否能让我们看到标记为 MethodImplOptions.InternalCall 的代码?

最佳答案

您需要 CLR 的源代码才能查看这些方法的实现。这有点难获得,Microsoft 没有发布它,也没有包含在引用源中。

只要该方法是“旧”的,自 .NET 2.0 以来可用,那么您就可以从 SSCLI20 source code 中获得机会。 .当然,您将看到代码的过时版本的风险非零。但足以了解它的外观并且通常仍然准确。

开始搜索代码的起点是 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] 属性添加许多新的内部方法并支持完全不同的额外互操作机制。据我所知,没有什么好的方法可以查看这些添加内容的来源。


更新:现在可从 CoreCLR project 获得源代码.该表已从 ecall.cpp 移至 ecalllist.h,机制仍然相同。请记住,这是 CLR 的 .NETCore 版本,桌面版本源代码仍然是封闭源代码。然而,这两个版本可能有很多共同点。

关于c# - 如何查看标记为 MethodImplOptions.InternalCall 的方法代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16579078/

相关文章:

c# - System.Object 类和结构之间的关系

c# - 从 DataTable 获取单个值的最佳方法?

c# - 列出连接到 Windows PC 的所有 USB 音频耳机

时间:2019-03-17 标签:c#nunitintegrationtestingwithexception

c# - 如何获取当前正在运行的应用程序列表?

c# - Windows 7 64 位上带有 Assembly.LoadFile 的 FileNotFoundException

.net - 单个进程中可以加载多少个运行时 (CLR)?

.net - ASP.NET:如何将值从本地资源传递给字符串?

clr - 为什么具有 PE​​Verified 堆栈溢出场景 (maxstack) 的程序不会使 CLR 崩溃?

c# - 是否可以将标有 MethodImplOptions.InternalCall 的方法链接到它的实现?