April 10, 2003
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
April 10, 2003

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