2013-05-16 14 views
15

Kiedy użycie ILSpy sprawdzić kod System.String znalazłem istnieją pewne metody oznaczone jako MethodImplOptions.InternalCall takie jak:Jak wyświetlić kod metody oznaczonej jako MethodImplOptions.InternalCall?

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

wiem MethodImplOptions.InternalCall oznacza ten sposób realizowany jest natywnie przez wspólny język środowisko uruchomieniowe do zoptymalizowanego kodu w celu poprawy wydajności.

Moje pytanie brzmi: czy to mimo wszystko może umożliwić nam zobaczyć kod oznaczony jako MethodImplOptions.InternalCall?

+3

Będziesz musiał spojrzeć na leżący u podstaw kodu C. Jest to również obsługiwane w różny sposób między strukturami, tj. Normalny vs mikro. – leppie

+0

Możesz uzyskać "Shared Source" od Microsoft dla wielu elementów CLR. Nie sprawdziłem, ale myślę, że należy uwzględnić implementację 'System.String' - zarówno części zarządzane, jak i natywne. Szczegółowe informacje można znaleźć na stronie http://referencesource.microsoft.com/. –

+1

@BenVoigt. Dziękujemy za informacje. Dostaję źródło od Microsoft, aw źródłowym pliku String ma następujące komentarze: '** Cel: Twoja ulubiona klasa String. Metody macierzyste ** są zaimplementowane w StringNative.cpp'. Jednak wygląda na to, że MS nie opublikowało tego pliku. – 2power10

Odpowiedz

12

Musisz kod źródłowy dla CLR, aby zobaczyć realizację tych metod. To trochę trudne, Microsoft nie publikuje go i nie jest on objęty Źródłem Odniesienia.

Dopóki metoda jest "stara", dostępna od wersji .NET 2.0, będziesz mieć do niej dostęp z poziomu SSCLI20 source code. Przy niezerowym ryzyku będziesz musiał spojrzeć na nieaktualną wersję kodu oczywiście. Ale wystarczająco dobre, aby uzyskać pojęcie, jak to wygląda i często nadal dokładne.

Punktem wyjścia do rozpoczęcia poszukiwania kodu jest clr/src/vm/ecall.cpp plik kodu źródłowego. Zawiera tabele, które jitter szuka wewnętrznych metod. Sekcja to istotne dla nativeCompareOrdinalEx() wygląda następująco:

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

Uwaga jak FCFuncElement ma nazwę metody jako ciąg i wskaźnik funkcji do C++, który implementuje metody wewnętrznego połączenia. Otworzenie drzewa kodu źródłowego przeniesie cię do clr/src/vm/comstring.cpp. Nie będę nudził każdego z kodem C++, po prostu sam się rozejrzyj.

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

wyszukiwania CaseInsensitiveCompHelper() i FastCompareStringHelperAligned() zabierze Cię do rzeczywistych wdrożeń, odpowiednio, wielkości liter i rozróżniana funkcji porównania w tym samym pliku kodu źródłowego.

Jedyne co godne jest to, że CLR wersja 4 wprowadziła pewne zmiany do tego mechanizmu. Dodanie wielu nowych wewnętrznych metod i wspieranie zupełnie innego dodatkowego mechanizmu współdziałania za pomocą atrybutu [DllImport] dla fałszywej biblioteki DLL o nazwie "QCall". Nie ma dobrego sposobu na znalezienie źródła tych dodatków, które znam.


AKTUALIZACJA: źródło jest teraz dostępne z poziomu CoreCLR project. Tabela została przeniesiona z ecall.cpp do ecalllist.h, mechanika wciąż jest taka sama. Należy pamiętać, że jest to wersja .NETCore środowiska CLR, źródło wersji dla komputerów stacjonarnych nadal jest źródłem zamkniętym. Obie wersje mają jednak wiele wspólnego.

1

jako ciąg help mówi, że są „realizowany w samej CLR”, więc trzeba konsultować swoje źródła C++ lub demontaż.

Zasadniczo pliki zawierające mechanizm CLR są kilkoma natywnymi plikami DLL w folderze %WINDIR%\Microsoft.NET\Framework\<.NET engine version>, głównie mscor*.dll i clr.dll. Korzeń NET DLL, mscoree.dll jest w System32 ale wydaje się jedynie pełnić rolę wyrzutni.

Ponieważ implementacje metod typu InternalCall są szczegółami implementacji, nie ma gwarancji, że metody te są implementowane w spójny sposób, np.że istnieje nawet ich globalny rejestr.

E.g. deasemblowanie pokazuje, że natywne metody .NET 4 System.String są zaimplementowane w clr.dll i odwołują się do struktury podobnej do katalogu, podczas gdy System.Deployment.Application.NativeMethods.IClrRuntimeInfo jest wspierane przez klasę COM w mscoreei.dll, przy czym metody są po prostu jej wirtualnymi funkcjami.

Powiązane problemy