Skip to content

Fața nevăzută a CLR-ului

1 June 2008

Eram curios cum funcționează metoda Assembly.Load – nu mai conteză de ce. Ca norocul, am pe calculator Shared Source Common Language Infrastructure 2.0 (de pe DVD-ul ARK, dar daca vreti, il puteti lua si de la Microsoft Research sub numele de Rotor). SSCLI sunt sursele de la .NET Framework, compilatorul de C# și altele, distribuite ca shared source.

După cum ziceam, caut Assembly.Load și găsesc declarația în /clr/src/bcl/system/reflection/Assembly.cs. Metoda apelează nLoad. Caut nLoad și găsesc în același fișier următoarea declarație:

[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern Assembly nLoad(
    AssemblyName fileName,
    String codeBase,
    Evidence assemblySecurity,
    Assembly locationHint,
    ref StackCrawlMark stackMark,
    bool throwOnFileNotFound,
    bool forIntrospection);

Sunt curios dacă pot și eu apela metoda nLoad. Aflu rapid că nu – StackCrawlMark este un alias declarat la începutul fișierului ca

using StackCrawlMark = System.Threading.StackCrawlMark;

unde System.Threading.StackCrawlMark are vizibilitatea internal – adică nu poate fi utilizat în afara assembly-ului în care apare😦 OK, totuși, ce înseamnă atributul

[MethodImplAttribute(MethodImplOptions.InternalCall)]?

Cică, spune MSDN, atributul denotă o metodă implementată chiar în CLR. După încă puține săpături, descopăr toate metodele astfel implementate în fișierul ecall.cpp (/clr/src/vm/echall.cpp) – ecall probabil de la Engine Call. Chiar dacă Base Class Library e scris în C#, mașina virtuală e scrisă în C++. În fișier este o listă măricică de funcții care sunt apelate de BCL cu ajutorul atributului de mai sus.

De curiozitate, încerc să apelez și eu o astfel de metodă – nu nLoad pentru că nu pot din cauza lui StackCrawlMark, dar găsesc ceva mai simplu: string GetFullName(). Declar și eu frumos

[MethodImpl(MethodImplOptions.InternalCall)]
internal extern static string GetFullName();

și apelez

Console.WriteLine(GetFullName());

Să nu uit de using System.Runtime.CompilerServices pentru cine vrea să refacă experimentul – acolo e declarat atributul MethodImpl.

Rezultatul? Excepție de tip System.Security.SecurityException: ECall methods must be packaged into a system module. Deci apelurile de tip InternalCall pot fi făcute doar din mscorlib.dll. Asta este. Măcar acum știu de existența lor.

From → code complete

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: