2013-05-16 18 views
15

Khi sử dụng ILSpy để kiểm tra mã của System.String, tôi thấy có một số phương pháp đánh dấu là MethodImplOptions.InternalCall như:Cách xem mã của phương thức được đánh dấu là MethodImplOptions.InternalCall?

[SecurityCritical] 
[MethodImpl(MethodImplOptions.InternalCall)] 
internal static extern int nativeCompareOrdinalEx(string strA, int indexA, string strB, int indexB, int count); 

Tôi biết MethodImplOptions.InternalCall nghĩa phương pháp này được thực hiện bởi natively ngôn ngữ chung thời gian chạy để tối ưu hóa mã để cải thiện hiệu suất.

Câu hỏi của tôi là: Dù sao có thể cho phép chúng tôi xem mã được đánh dấu là MethodImplOptions.InternalCall?

+3

Bạn sẽ phải xem mã C cơ bản. Điều này cũng được xử lý khác nhau giữa các khung công tác, ví dụ như bình thường so với vi mô. – leppie

+0

Bạn có thể nhận được "Nguồn chia sẻ" từ Microsoft cho nhiều phần của CLR. Tôi chưa kiểm tra nhưng tôi nghĩ rằng việc triển khai 'System.String' phải được bao gồm - cả phần được quản lý lẫn phần gốc. Xem http://referencesource.microsoft.com/ để biết chi tiết –

+1

@BenVoigt cảm ơn thông tin của bạn. Tôi lấy nguồn từ Microsoft, và trong tệp nguồn của String, nó có các chú thích sau: '** Mục đích: Lớp String yêu thích của bạn. Phương thức gốc ** được triển khai trong StringNative.cpp'. Tuy nhiên, có vẻ như MS không công khai tệp này. – 2power10

Trả lời

3

Kể từ bây giờ CoreCLR is open source, vì vậy chúng tôi có thể kiểm tra mã nội bộ.

Bạn có thể tìm kiếm từ khóa COMString::CompareOrdinalEx trong stringnative.cpp để xem triển khai nội bộ.

12

Bạn sẽ cần mã nguồn cho CLR để xem việc triển khai các phương pháp này. Đó là một chút khó khăn để đi qua, Microsoft không xuất bản nó và nó không được bao phủ bởi các nguồn tham khảo.

Miễn là phương thức "cũ", có sẵn từ .NET 2.0, khi đó bạn sẽ có ảnh tại số SSCLI20 source code. Với một rủi ro khác không phải là bạn sẽ xem xét một phiên bản lỗi thời của mã khóa học. Nhưng đủ tốt để có được một ý tưởng nó trông như thế nào và thường vẫn chính xác.

Điểm bắt đầu để bắt đầu tìm kiếm mã là tệp mã nguồn clr/src/vm/ecall.cpp. Nó chứa các bảng mà jitter tìm kiếm các phương thức nội bộ. Phần có liên quan cho nativeCompareOrdinalEx() trông như thế này:

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.. 
} 

Lưu ý cách FCFuncElement có tên phương pháp như là một chuỗi và một con trỏ hàm với phương pháp C++ mà thực hiện các cuộc gọi nội bộ. Tham lam cây mã nguồn sau đó đưa bạn đến clr/src/vm/comstring.cpp. Tôi sẽ không mang tất cả mọi người với mã C++, chỉ cần có một cái nhìn cho chính mình.

/*================================CompareOrdinal===============================*/ 
FCIMPL3(INT32, COMString::FCCompareOrdinal, StringObject* strA, StringObject* strB, CLR_BOOL bIgnoreCase) { 
    // Yadayada 
    //... 
} 

Tìm kiếm CaseInsensitiveCompHelper() và FastCompareStringHelperAligned() sẽ đưa bạn đến việc triển khai thực tế của, tương ứng, chức năng so sánh case-insensitive và trường hợp nhạy cảm trong cùng một tập tin mã nguồn.

Điều duy nhất đáng chú ý về điều này là CLR phiên bản 4 đã thực hiện một số thay đổi đối với cơ chế này. Thêm rất nhiều phương thức nội bộ mới và hỗ trợ một cơ chế interop bổ sung hoàn toàn khác thông qua thuộc tính [DllImport] cho một DLL giả có tên "QCall". Không có cách nào tốt để xem nguồn cho những bổ sung mà tôi biết.


CẬP NHẬT: nguồn hiện khả dụng từ CoreCLR project. Bảng đã được chuyển từ ecall.cpp sang ecalllist.h, các cơ chế vẫn như cũ. Hãy ghi nhớ rằng đây là phiên bản .NETCore của CLR, nguồn phiên bản máy tính để bàn vẫn là nguồn đóng. Hai phiên bản tuy nhiên có khả năng có nhiều điểm chung.

1

Khi chuỗi trợ giúp cho biết, chúng được "triển khai trong chính CLR", vì vậy bạn sẽ cần tham khảo nguồn C++ hoặc tháo gỡ.

Nói chung, các tệp bao gồm công cụ CLR là một vài tệp DLL gốc trong thư mục %WINDIR%\Microsoft.NET\Framework\<.NET engine version>, chủ yếu là mscor*.dllclr.dll. DLL gốc .NET, mscoree.dll, nằm ở System32 nhưng dường như chỉ hoạt động như một trình khởi chạy.

Do triển khai phương pháp InternalCall là chi tiết triển khai, không đảm bảo rằng các phương pháp đó được triển khai theo cách nhất quán, ví dụ:thậm chí có một số đăng ký toàn cầu của chúng.

Ví dụ: disassembling cho thấy rằng phương thức gốc của .NET 4 System.String được thực hiện trong clr.dll và được tham chiếu trong cấu trúc giống thư mục trong khi System.Deployment.Application.NativeMethods.IClrRuntimeInfo được hỗ trợ bởi lớp CLRRuntimeInfoImpl COM trong mscoreei.dll, các phương thức đơn giản là các hàm ảo của nó.

Các vấn đề liên quan