2012-03-17 15 views
17

Tengo un problema con C#, me gustaría obtener un puntero de un método en mi código, pero parece imposible. Necesito el puntero del método porque no quiero utilizarlo usando WriteProcessMemory. ¿Cómo obtendré el puntero?Puntero de función C#?

Ejemplo de código

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

Ese no es un código válido de C#. ¿que estás tratando de hacer? – gdoron

+4

parece similar (muy) a esta pregunta [aquí] (http://stackoverflow.com/questions/2550218/how-to-store-a-function-pointer-in-c-sharp). también podría ayudarte. –

+1

Se está acercando al problema de la manera (totalmente) incorrecta. ¿Por qué quieres no-op el método? Puede hacerlo, pero de manera diferente, dependiendo de su código de llamada. –

Respuesta

19

EDIT: He leído mal su pregunta y no vi lo de querer NOP hacer una declaración con la manipulación de la memoria prima. Me temo que esto no se recomienda porque, como dice Raymond Chen, el GC mueve cosas en la memoria (de ahí la palabra clave 'fijada' en C#). Probablemente puedas hacerlo con reflexión, pero tu pregunta sugiere que no tienes una comprensión sólida de la CLR. De todos modos, de nuevo a mi respuesta irrelevante original (donde pensé que sólo quería información sobre el uso de los delegados):

C# no es un lenguaje de programación;)

De todos modos, C# (y el CLR) tiene " punteros de función "- excepto que se llaman" delegados "y están fuertemente tipados, lo que significa que debe definir la firma de la función además de la función que desea llamar.

En su caso, usted tendría algo como esto:

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

Usted _can_ nop it (sortove). Cree una 'Function3' que no tenga cuerpo y cambie el delegado a' Function3' y haga que 'Main' llame al delegado. –

2

Desearía es útil

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

Reescritura de un método no se puede hacer directamente desde el código administrado, sin embargo, la la aplicación de perfiles .net no administrada se puede usar para hacer esto. Ver this artículo msdn por ejemplo sobre cómo usarlo.

18

Sé que esto es muy antiguo, pero un ejemplo de algo así como un puntero de función en C# sería así:

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

... y luego en su principal o donde sea:

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

luego de llamar a la función original,

myPointer(); 
myPointer2(); 

Si tiene argumentos a sus métodos, entonces es tan simple como añadiendo argumentos genéricos a su acción:

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

doItWithAString("help me"); 

O si necesita devolver un valor:

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

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

Guau, excelente respuesta. Tal vez no sea específico para esta pregunta, pero aprendí algo y resolvió mi problema. – pelesl

+0

+1 ¡La mejor respuesta! Gracias por compartir ejemplos para cada escenario (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 .. usar esto para pasar a métodos alrededor. No tiene sentido en este contexto, pero eso es básicamente cómo lo usaría

+1

Esta debería ser la nueva respuesta aceptada. – Roman

Cuestiones relacionadas