2010-02-09 35 views
2

我想知道是否可以在運行時動態注入函數參數。對於例如我有兩個重載方法的類說向c中的函數調用動態注入參數#

Class C1 
{ 
    public static void Func1(object o) 
    { 
    } 

    public static void Func1() 
    { 
    }  
} 

Class C2 
{ 

    public void Func1() 
    { 
     C1.Func1(); 
    } 
} 

現在,是有可能與給重載方法C1.Func1(對象o)的呼叫動態地替換調用FUNC1()傳遞在任一「這個」或者類型對象作爲參數。因此,在我調用C1.Func1()時,我的代碼應該調用C1.Func1(this);

+0

我猜他想攔截/分流已經編譯的代碼片段,但他沒有源代碼訪問權限,但知道公衆。 – 2010-02-09 18:53:26

+1

一種方法是將exe反編譯到MSIL,進行更改並重新編譯它。 – Amirshk 2010-02-09 18:55:08

回答

3

我假設「動態」是指後編譯時解決方案,但不一定在運行時。後者會更具挑戰性,但可以完成。對於前者來說,如果你知道一些IL就相當容易。我注意到,C2.Func1編譯成類似

.method public hidebysig instance void Func1() cil managed { 
    call void SomeNamespace.C1::Func1() 
    ret 
} 

,你可以輕鬆地與

.method public hidebysig instance void Func1() cil managed { 
    ldarg.0 
    call void SomeNamespace.C1::Func1(object) 
    ret 
} 

更換。這是因爲,參數零的實例方法始終是當前實例的this參考,我們可以推它在與指令ldarg.0的堆棧上。此外,我們只是簡單地將我們所調用的方法的簽名從無參數方法替換爲接受單個object作爲參數的方法。

您可以使用ildasm輕鬆地反編譯爲IL,並使用ilasm重新編譯。

+0

謝謝傑森,這當然有用,但是你能否更詳細地解釋一下你提出的另一個選項,即在運行時,是否意味着使用Am建議的Profiler API? – ilias 2010-02-10 09:21:40

1

有幾個選項:

  1. 反編譯二進制MSIL,手工做的修改並重新編譯。
  2. 用戶.NET剖析API注入代碼,這裏是一個[文章]討論它。
  3. 類似問題code-injection-with-c

的代碼注入將是攔截功能,無需論證,並召回有一個參數的函數。

0

由於您的方法是靜態的,因此無法獲取調用對象。

你的選擇是讓你的方法非靜態並創建一個C1對象,或者將C2(this)對象作爲參數傳入。

2

您可以使用擴展方法:

public static class C1Extensions 
{ 
    public static void Func1(this C1 o) 
    { 
     // ... 
    } 
} 

public class C1 
{ 
    public void Foo() 
    { 
     this.Func1(); 
    } 
} 
+0

打我30秒... – 2010-02-09 19:05:12

+0

+1,即將發佈相同的內容,但仍需要使用「this」關鍵字來調用它。 – 2010-02-09 19:05:32

0

你有沒有想過使用擴展方法來做到這一點?

public static class C1WrappingExtensions { 
    public static void Func1(this object instance) { 
     C1.Func(instance); 
    } 
} 

// Now you can just call Func1() on any object... 
var me = new Whatever(); 
me.Func1();