2012-03-17 25 views
17

C# ile ilgili bir sorun yaşıyorum Kodumda bir yöntemin bir işaretçisini almak istiyorum, ancak imkansız görünüyor. Metodun işaretçisine ihtiyacım var çünkü WriteProcessMemory kullanarak no-op yapmak istiyorum. İşaretçiyi nasıl alabilirim?C# fonksiyon işaretçisi?

Örnek kod

main() 
{ 
    function1(); 
    function2(); 
} 

function1() 
{ 
    //get function2 pointer 
    //use WPM to nop it (I know how, this is not the problem) 
} 
function2() 
{ 
    Writeline("bla"); //this will never happen because I added a no-op. 
} 
+1

Geçerli bir C# kodu değil. ne yapmaya çalışıyorsun? – gdoron

+4

bu soruya benzer (çok) görünüyor [burada] (http://stackoverflow.com/questions/2550218/how-to-store-a-function-pointer-in-c-sharp). ayrıca size yardımcı olabilir. –

+1

Soruna (tamamen) yanlış şekilde yaklaşıyorsunuz. Yöntemi neden kullanmak istemiyorsunuz? Bunu yapabilirsiniz - ama çağrı kodunuza bağlı olarak farklı. –

cevap

19

DÜZENLEME: Sorunuzu yanlış yorumlamak ve ham bellek manipülasyon yapıyor bir açıklama NOP isteyen yaklaşık biraz görmedik. Korkarım ki bu tavsiye edilmez çünkü Raymond Chen'in dediği gibi, GC hafızada bir şeyler taşıyor (bu yüzden C# 'deki' sabitlenmiş 'anahtar kelime). Muhtemelen yansıma ile yapabilirsiniz, ama sorunuz CLR'nin güçlü bir kavrayışına sahip olmadığını gösterir. Neyse, tekrar orijinal alakasız cevap (düşündüğüm yerde sadece delegelerin nasıl kullanılacağı hakkında bilgi istedim):

C# bir kodlama dili değildir;)

neyse), C# (ve CLR "vardır işlev işaretçileri "-" delegeler "olarak adlandırılırlar ve güçlü yazılırlar, yani çağırmak istediğiniz işleve ek olarak işlevin imzasını tanımlamanız gerekir. Ancak

public static void Main(String[] args) { 

    Function1(); 

} 

// This is the "type" of the function pointer, known as a "delegate" in .NET. 
// An instance of this delegate can point to any function that has the same signature (in this case, any function/method that returns void and accepts a single String argument). 
public delegate void FooBarDelegate(String x); 


public static void Function1() { 

    // Create a delegate to Function2 
    FooBarDelegate functionPointer = new FooBarDelegate(Function2); 

    // call it 
    functionPointer("bla"); 
} 

public static void Function2(String x) { 

    Console.WriteLine(x); 
} 
+0

Siz _can_ nop it (sortove). Vücuduna sahip olmayan ve "Function3" öğesine delege değiştiren ve 'Ana' delege çağrısı yapan '' Fonksiyon3''ü oluşturun. –

2

Ben bir yöntem Yeniden Yazma

class Program 
{ 

    static void Main(string[] args) 
    { 
     TestPointer test = new TestPointer(); 
     test.function1(); 
    } 
} 
class TestPointer 
{ 
    private delegate void fPointer(); // point to every functions that it has void as return value and with no input parameter 
    public void function1() 
    { 
     fPointer point = new fPointer(function2); 
     point(); 
    } 
    private void function2() 
    { 
     Console.WriteLine("Bla"); 
    } 
} 
1

yönetilen kod doğrudan yapılamaz yararlıdır arzu ediyorum: Senin durumunda

, böyle bir şey olurdu unmanaged .net profilleme api bunu yapmak için kullanılabilir. Örneğin nasıl kullanılacağı hakkında this msdn makalesine bakın.

18

Bu çok eski biliyorum ama C# bir işlev işaretçisi gibi bir şey bir örnek şöyle olacaktır: sonra

class Temp 
{ 
    public void DoSomething() {} 
    public void DoSomethingElse() {} 
    public void DoSomethingWithAString(string myString) {} 
    public bool GetANewCat(string name) { return true; } 
} 

... ve sizin ana veya yerde:

var temp = new Temp(); 
Action myPointer = null, myPointer2 = null; 
myPointer = temp.DoSomething; 
myPointer2 = temp.DoSomethingElse; 

sonra

myPointer(); 
myPointer2(); 

Eğer yöntemlere argümanları varsa, o zaman kadar basit, orijinal işlevi çağırmak için

Action<string> doItWithAString = null; 
doItWithAString = temp.DoSomethingWithAString; 

doItWithAString("help me"); 

Veya bir değer döndürmek için gerekirse: senin Harekete jenerik argümanlar ekleyerek

Func<string, bool> getACat = null; 
getACat = temp.GetANewCat; 

var gotIt = getACat("help me"); 
+1

Vay, harika cevap. Belki bu soruya özgü değil, ama bir şey öğrendim ve problemimi çözdü. – pelesl

+0

+1 En iyi cevap! Her senaryo için örnekler paylaştığınız için teşekkür ederiz (void -> void, args -> void, args -> return) – bigp

9
public string myFunction(string name) 
{ 
    return "Hello " + name; 
} 

public string functionPointerExample(Func<string,string> myFunction) 
{ 
    myFunction("Theron"); 
} 

Func functionName .. etrafında yöntemleri geçmesine bunu kullanın. Bu bağlamda bir anlam ifade etmemektedir, ancak temelde nasıl kullanacağınız bu

+1

Bu yeni kabul edilen cevap olmalıdır. – Roman