2011-01-29 9 views
8

पर किसी विधि में आईएल इंजेक्ट करने के लिए कैसे शीर्षक कम या ज्यादा कहता है। this लेख के आधार पर, मैं इस के साथ आ गया है:रनटाइम

public static unsafe void Replace(this MethodBase destination, MethodBase source) 
{ 
    IntPtr srcHandle = source.MethodHandle.GetFunctionPointer(); 
    IntPtr dstHandle = destination.MethodHandle.GetFunctionPointer(); 

    int* dstPtr = (int*)dstHandle.ToPointer(); 
    *dstPtr = srcHandle.ToInt32(); 
} 

यह वास्तव में काम करता है ... कभी कभी -.-

उदाहरण के लिए, इस काम करता है।

public static class Program 
{ 
    public static void Main(string[] args) 
    { 
     MethodInfo methodA = typeof(Program).GetMethod("A", BindingFlags.Public | BindingFlags.Static); 
     MethodInfo methodB = typeof(Program).GetMethod("B", BindingFlags.Public | BindingFlags.Static); 

     methodA.Replace(methodB); 

     A(); 
     B(); 
    } 

    public static void A() 
    { 
     Console.WriteLine("Hai World"); 
    } 

    public static void B() 
    { 
     Console.WriteLine("Bai World"); 
    } 
} 

हालांकि, यह (SEHException) नहीं है। मैंने जो कुछ किया वह कार्य बदल गया था जिसमें कार्यों को परिभाषित किया गया था।

public static class Program 
{ 
    public static void Main(string[] args) 
    { 
     MethodInfo methodA = typeof(Program).GetMethod("A", BindingFlags.Public | BindingFlags.Static); 
     MethodInfo methodB = typeof(Program).GetMethod("B", BindingFlags.Public | BindingFlags.Static); 

     methodA.Replace(methodB); 

     A(); 
     B(); 
    } 

    public static void B() 
    { 
     Console.WriteLine("Bai World"); 
    } 

    public static void A() 
    { 
     Console.WriteLine("Hai World"); 
    } 
} 

लेख में कोड के लिए ... मैं इसे बिल्कुल काम नहीं कर सका।

कोई विचार/विकल्प?

+0

आप ऐसा क्यों करना चाहते हैं? यह एक भयानक विचार की तरह लगता है। – Amy

+2

चिंता न करें - कुछ भी दुर्भावनापूर्ण नहीं है। सिर्फ ज्ञान के लिए: डी – YellPika

+0

मेरा मानना ​​है कि ऐसा करने का एकमात्र सुरक्षित तरीका असेंबली लोड होने से पहले कोड को इंजेक्ट करना है। – porges

उत्तर

8

यह बहुत सारी बुरी धारणाएं कर रहा है जो आपको गधे में काट देगा।

पहली चीजें पहले, प्रतिबिंब के माध्यम से लौटाई गई संरचना किसी भी तरह से किसी भी रनटाइम संरचनाओं को इंगित करने की गारंटी नहीं देती है। जैसे पॉइंटर्स को संशोधित करने का प्रयास करना इसमें शामिल है या रिटर्न सिर्फ सादा गलत है।

दूसरा, यदि आप पूर्व/पोस्ट विधि कॉल इनवेरिएंट (उदाहरण के रूप में) इंजेक्शन की तरह कुछ करना चाहते हैं तो आपको शायद रनटाइम प्रॉक्सी ऑब्जेक्ट्स बनाना चाहिए और इसके बजाय इंजेक्ट करना चाहिए। या एमिट नेमस्पेस के माध्यम से गतिशील विधि निर्माण का उपयोग करें। अनियंत्रित/अज्ञात व्यवहार (जैसे उपरोक्त कोड) के माध्यम से चीजों में हेरफेर करने का प्रयास करना सिर्फ काम नहीं करेगा।

आपको यह भी समझने की आवश्यकता है कि जेआईटी यह तय करेगा कि यह कब होगा। कभी-कभी यह पूरी कक्षा के खिलाफ चलता है, और कभी-कभी यह केवल एक विधि के खिलाफ चलता है। आपका कोड यह निर्धारित करने का कोई प्रयास नहीं करता है कि विधि अभी तक JITted है या नहीं, और अंधाधुंध मानता है कि फ़ंक्शन पॉइंटर लौटाया जा सकता है।

+0

मुझे नाम पसंद है और मुझे शो पसंद आया। आपका दिन शुभ हो! – Amy

+0

उस मामले में ... ए) तो फिर यह वास्तव में क्या इंगित करता है? बी) मैं कैसे पता लगा सकता हूं कि कोई विधि जिट की गई है या नहीं? – YellPika

+0

बी) आप तब तक नहीं कर सकते जब तक कि निष्पादन से पहले कार्यक्रम को एनजीएन के माध्यम से संसाधित नहीं किया जाता। – Amy