D の delegate について

わけわか、と書かれてしまったよ、ということについて、難しいというより説明が全くなされていないからだろうと思って、少し説明を。 delegate は 2 つのポインタからなりたっています。最初の要素にはスタックフレームへのポインタが、2つ目の要素には関数ポインタが入っています。調べてみるとすぐわかります。

void main() {
    auto dg = () { printf("hello\n"); };
    void** p = cast(void**)&dg;
    printf("%p %p\n", p[0], p[1]);

    void* ebp;
    asm { mov ebp, EBP; };
    printf("%p\n", ebp);

    void(*fp)() = cast(void(*)())p[1];
    fp();
}

main 内の部分で 1,2 個目のポインタの値を表示してます。うちでは 0xbffd3dd8 0x804a06c と表示されました。で、 asm { mov ebp, EBP; }; で ebp の値を拾ってきて表示してやります。これも 0xbffd3dd8 になるため、 1つ目のポインタはなるほどスタックフレームへのポインタです。 2つ目のポインタが関数ポインタであることを示すには、単純に実行してやるのが速いと思います。関数ポインタにキャストした上で、実行してやっています。結果は hello と表示されます。

その上で k.inaba さんは、 1つ目のポインタの部分を調べてスタックフレームをいくらかヒープにコピーして、1つ目のポインタをそこへのポインタにしてやればいい…ということをされて、その「いくらか」が24Byte決め打ちだったので、スタックフレーム巻戻していってその差を調べればいいよね…という補足が私というか。

あれ詳説しようとしたのにえらい雑な説明だぞ。

なにかあれば下記メールアドレスへ。
shinichiro.hamaji _at_ gmail.com
shinichiro.h