Dove esiste effettivamente NativegetUninitializedObject?
-
28-10-2019 - |
Domanda
Ero curioso di sapere alcune cose di serializzazione, quindi sono andato in giro FormatterServices
e ho trovato un metodo chiamato nativeGetUninitializedObject
Ciò gestisce effettivamente l'inizializzazione (senza chiamare il custroctor) di un determinato tipo. Questo metodo è decorato con il extern
Parole chiave e il seguente attributo: [MethodImpl(MethodImplOptions.InternalCall), SecurityCritical]
Mi chiedo: dove esiste effettivamente questo metodo? Quale codice chiama il CLR per ottenere il tipo dato inizializzato (senza chiamare il costruttore)?
Soluzione
Questo metodo esiste effettivamente nella parte nativa del CLR. Il MethodImplOptions.InternalCall
Significa una chiamata che viene inoltrata al codice nativo CLR ed è implementata lì.
Da Msdn:
Specifica una chiamata interna. Una chiamata interna è una chiamata a un metodo implementato nel corso del linguaggio comune stesso.
Altri suggerimenti
Il metodo esiste nel CLR. Il compilatore JIT ha accesso a una tabella all'interno del CLR che contiene gli indirizzi di tutte le funzioni di MethodImploptions. La sezione della tabella che è rilevante per la tua domanda sembra questo nel codice sorgente SSCLI20 (CLR/SRC/VM/ECALL.CPP):
FCFuncStart(gSerializationFuncs)
FCFuncElement("nativeGetSafeUninitializedObject", ReflectionSerialization::GetSafeUninitializedObject)
FCFuncElement("nativeGetUninitializedObject", ReflectionSerialization::GetUninitializedObject)
FCFuncEnd()
Per jit la chiamata del metodo, cerca semplicemente il nome della funzione in quella tabella e genera un'istruzione di chiamata diretta all'indirizzo della funzione elencato nella tabella. Transizione diretta molto veloce e diretta dal codice gestito al codice scritto in C ++ all'interno del CLR.
Il metodo ReflectionSERIALIZION :: getUniniTitializeBject () vive all'interno di CLR/SRC/VM/ReflectionInvocation.CPP, è troppo grande per essere pubblicato qui. Puoi avere uno sguardo al codice sorgente SSCLI20 scaricabile. C'è un sacco di controllo di errore, quindi una chiamata a un metodo RAW Allocate () per allocare la memoria per l'oggetto. Nessuna chiamata costruttore.