web-dev-qa-db-ja.com

C#関数ポインタ?

C#に問題があります。コード内のメソッドのポインターを取得したいのですが、不可能なようです。 WriteProcessMemoryを使用して何も操作しないため、メソッドのポインターが必要です。ポインターはどのように取得しますか?

サンプルコード

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.
}
24
user1276333

これは非常に古いことは知っていますが、C#の関数ポインターのようなものの例は次のようになります。

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

...そしてメインまたはどこでも:

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

次に、元の関数を呼び出すために、

myPointer();
myPointer2();

メソッドに引数がある場合、アクションに一般的な引数を追加するのと同じくらい簡単です。

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

doItWithAString("help me");

または、値を返す必要がある場合:

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

var gotIt = getACat("help me");
32
outbred

編集:あなたの質問を誤解し、生のメモリ操作を行う文をNOPしたいということについて少しも知りませんでした。 Raymond Chenが言うように、GCはメモリ内を移動するため、これは推奨されません(C#の「固定」キーワード)。あなたはおそらくリフレクションでそれを行うことができますが、あなたの質問はあなたがCLRを強く把握していないことを示唆しています。とにかく、元の無関係な答え(デリゲートの使用方法に関する情報が欲しいだけだと思った場所)に戻ります。

C#はスクリプト言語ではありません;)

とにかく、C#(およびCLR)には「関数ポインター」があります-「デリゲート」と呼ばれ、強く型付けされていることを除いて、呼び出す関数に加えて関数の署名を定義する必要があります。

あなたの場合、次のようなものがあります:

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);
}
22
Dai
public string myFunction(string name)
{
    return "Hello " + name;
}

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

Func functionName ..これを使用してメソッドを渡します。このコンテキストでは意味がありませんが、基本的にはそれを使用する方法です

14
Thiren Govender

私はそれが有用であることを望みます

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");
    }
}
2
Mahdi

メソッドの書き換えはマネージコードから直接行うことはできませんが、アンマネージ.netプロファイリングAPIを使用してこれを行うことができます。使い方の例については this msdnの記事をご覧ください。

1
Mike Zboray