Last update April 10, 2003

Helmut Leitner /
Delegate Hack



This snippet came from trying to write a benchmark module (it's not yet ready to post it). There I had to write separate redundant code to test functions and delegates, because there is no way to convert them easily.

Well, but then - what can one do? At least understand how delegates are handled and implemented internally.


/* dghack.d (C) Helmut Leitner 2003, PD */

void delegate () dg;

struct s_delegate {
    void *pthis;
    void (*method)(void *pthis);
}
s_delegate *sdg;

void (*f)(void *pthis);

class TestDelegate {
    int id=1;
    this(int id) {
       this.id=id;
    }
    void print1() {
        printf("I'm the TestDelegate method print1\n");
    }
    void print2() {
        printf("I'm the TestDelegate method print2\n");
    }
    void print3() {
        printf("I'm a method called through an fp, my object.id=%d\n",id);
    }
    void print4() {
        printf("I'm a method that want's to be called through a delegate with this=%p\n",this);
    }
}

void print(out s_delegate *psd) {
    printf("pthis=%p method=%p\n",psd.pthis,(void *)psd.method);
}

void print_function(void *pthis) {
    printf("I'm a function called through a delegate\n");
}

int main (char[][] args) {
    TestDelegate td=new TestDelegate(1);

    dg= &td.print1;
    sdg=(s_delegate *)&dg;
    dg();
    print(sdg);

    dg= &td.print2;
    sdg=(s_delegate *)&dg;
    dg();
    print(sdg);

    printf("\n");

    // let's start hacking
    sdg.method=(void (*)(void *))print_function;
    dg();  // prints "I'm a function called ...."

    dg= &td.print3;

    sdg=(s_delegate *)&dg;
    f=sdg.method;
    f(td);  // printf "I'm a method ... id=1
    TestDelegate td2=new TestDelegate(42);
    f(td2); // printf "I'm a method ... id=42

    printf("\n");
    printf("This will only work if you compile using '-release'\n");

    dg= &td.print4;
    dg();
    sdg=(s_delegate *)&dg;
    sdg.pthis=null;
    dg();  // <=== this work's only with -release

    return 0;
}


FolderExamples
FrontPage | News | TestPage | MessageBoard | Search | Contributors | Folders | Index | Help | Preferences | Edit

Edit text of this page (date of last change: April 10, 2003 16:17 (diff))