Où nativeGetUninitializedObject existe réellement?
-
28-10-2019 - |
Question
J'étais curieux des choses de sérialisation alors je suis allé fouiner FormatterServices
et a trouvé une méthode appelée nativeGetUninitializedObject
qui gère en fait l'initialisation (sans appeler le custructor) d'un type donné. Cette méthode est décorée avec le mot-clé extern
et l'attribut suivant: [MethodImpl(MethodImplOptions.InternalCall), SecurityCritical]
Je suis à me demander: d'où vient cette méthode existe réellement? Quel code ne l'appel CLR pour obtenir le type donné initialisé (sans appeler le constructeur)?
La solution
Cette méthode existe réellement dans la partie native du CLR. Le MethodImplOptions.InternalCall
signifie un appel qui est transmis au code natif CLR et y est mis en œuvre.
De MSDN :
Indique un appel interne. Un appel interne est un appel à une méthode qui est mis en œuvre dans le Common Language Runtime lui-même.
Autres conseils
La méthode existe dans le CLR. Le compilateur JIT a accès à une table à l'intérieur du CLR qui contient les adresses de toutes les fonctions de MethodImplOptions.InternalCall. La section de la table qui est pertinent à votre apparence question comme cela dans le code source de SSCLI20 (clr / src / vm / ecall.cpp):
FCFuncStart(gSerializationFuncs)
FCFuncElement("nativeGetSafeUninitializedObject", ReflectionSerialization::GetSafeUninitializedObject)
FCFuncElement("nativeGetUninitializedObject", ReflectionSerialization::GetUninitializedObject)
FCFuncEnd()
Pour Jit l'appel de méthode, il semble simplement le nom de la fonction dans ce tableau et génère une instruction d'appel direct à l'adresse de fonction comme indiqué dans le tableau. Très rapide, transition directe du code managé à code écrit en C ++ dans le CLR.
Le ReflectionSerialization :: vie méthode GetUninitializedObject () à l'intérieur clr / src / vm / reflectioninvocation.cpp, il est trop grand pour poster ici. Vous pouvez jeter un oeil-voir le code source téléchargeable de SSCLI20. Il y a un tas de vérification d'erreur, puis un appel à une méthode brute Allouer () pour allouer la mémoire de l'objet. Aucun appel constructeur.