www.digitalmars.com         C & C++   DMDScript  

D - hacking to understand delegates

reply Helmut Leitner <leitner hls.via.at> writes:
The following code may give those with a hackers heart
some fun:

==============

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

import stream;
import c.stdio;

void delegate () dg;

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);
    }
}

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

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

s_delegate *sdg= (s_delegate *)&dg;

void (*f)(void *pthis);

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

    return 0;
}

==============
Output:
==============

I'm the TestDelegate method print1
pthis=00690FD0 method=00402030
I'm the TestDelegate method print2
pthis=00690FD0 method=00402044

I'm a function called through a delegate
I'm a method called through an fp, my object.id=1
I'm a method called through an fp, my object.id=42

--

The only thing I couldn't manage is call a method 
through a function with a null pointer (even if the 
code doesn't use this).

-- 
Helmut Leitner    leitner hls.via.at
Graz, Austria   www.hls-software.com
Apr 10 2003
parent Helmut Leitner <leitner hls.via.at> writes:
Helmut Leitner wrote:
 
 The only thing I couldn't manage is call a method
 through a function with a null pointer (even if the
 code doesn't use "this").
 
Well, this is working now too, although only together with '-release'. It seems that in the standard mode of the compiler the "delegate.this" pointer is checked to be valid. You find the reworked snippet "dghack.d" at: <http://www.prowiki.org/wiki4d/wiki.cgi?HelmutLeitner/Snippets> -- Helmut Leitner leitner hls.via.at Graz, Austria www.hls-software.com
Apr 10 2003