2012-03-17 16 views
17

Ho un problema con C#, mi piacerebbe ottenere un puntatore di un metodo nel mio codice, ma sembra impossibile. Ho bisogno del puntatore del metodo perché voglio farlo senza usare WriteProcessMemory. Come potrei ottenere il puntatore?Puntatore funzione C#?

codice di esempio

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

Questo non è un codice C# valido. Cosa stai cercando di fare? – gdoron

+4

sembra simile (molto) a questa domanda [qui] (http://stackoverflow.com/questions/2550218/how-to-store-a-function-pointer-in-c-sharp). potrebbe anche aiutarti. –

+1

Ti stai avvicinando al problema in (totalmente) modo sbagliato. Perché vuoi evitare il metodo? Puoi farlo, ma in modo diverso, a seconda del tuo codice di chiamata. –

risposta

19

EDIT: ho letto male la tua domanda e non vedere il bit di voler NOP una dichiarazione con il fare la manipolazione della memoria crudo. Temo che questo non sia raccomandato perché, come dice Raymond Chen, il GC sposta le cose in memoria (da qui la parola chiave "appuntata" in C#). Probabilmente lo puoi fare con la riflessione, ma la tua domanda suggerisce che non hai una forte conoscenza del CLR. Comunque, tornando alla mia risposta irrilevante originale (in cui ho pensato si voleva solo informazioni su come utilizzare i delegati):

C# non è un linguaggio di scripting;)

In ogni caso, C# (e il CLR) ha " puntatori di funzioni "- eccetto che sono chiamati" delegati "e sono fortemente tipizzati, il che significa che è necessario definire la firma della funzione oltre alla funzione che si desidera chiamare.

Nel tuo caso, si avrebbe qualcosa di simile:

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

Si _can_ nop (sortove). Crea un 'Function3' che non ha corpo e cambia il delegato in' Function3' e chiama 'Main' il delegato. –

2

mi augurerei è utile

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

riscrittura di un metodo non può essere fatto direttamente dal codice gestito, ma il può essere usato per fare ciò. Vedere l'articolo msgn this per esempio su come usarlo.

18

So che questo è molto vecchio, ma un esempio di qualcosa di simile a un puntatore a funzione in C# sarebbe stato così:

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

... e poi nel vostro principale o ovunque:

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

quindi chiamare la funzione originaria,

myPointer(); 
myPointer2(); 

Se avete argomenti per i vostri metodi, allora è così semplice come l'aggiunta di argomenti generici alla tua azione:

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

doItWithAString("help me"); 

Oppure, se avete bisogno di restituire un valore:

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

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

Wow, ottima risposta. Forse non specifico per questa domanda, ma ho imparato qualcosa e ha risolto il mio problema. – pelesl

+0

+1 Risposta migliore! Grazie per aver condiviso esempi per ogni scenario (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"); 
} 

Funz functionName .. utilizzare questo per passare metodi intorno. Non ha senso in questo contesto, ma questo è fondamentalmente il modo in cui lo useresti

+1

Questa dovrebbe essere la nuova risposta accettata. – Roman