Thread overview
Passing a delegate to a C function.
Feb 07, 2006
Walter Bright
Feb 08, 2006
Walter Bright
Feb 09, 2006
Stewart Gordon
Feb 10, 2006
Walter Bright
Feb 10, 2006
Stewart Gordon
February 07, 2006
Sorry for cross-posting but got no answer on d.D.l:


Hi.

I'm writing a binding to a C library. One of its functions has the following signature:

write_to_stream(surface_t* surface,
                write_func_t write_func,
                void* closure);

.... and write_func is:

alias status_t function(void* closure,
                        ubyte* data,
                        uint length) write_func_t;

This seemed to map perfectly to a D delegate. So I started looking in the reference for a way to obtain the stack frame and the function pointer of a non-static delegate but couldn't find it.

Then attempted to implement the trick, that was posted in the digitalmars.D newsgroup long time ago, of creating a union with the delegate and member functions for the stack and function pointer:

union WriteClosure
{
    /*extern(C)*/ status_t delegate (ubyte* data, uint length) dg;
    struct
    {
        // It's this the correct order?
        void* closure;
        write_func_t write_func;
    }
}

void writeToStream(OutputStream ostream)
{
    WriteClosure wc;
    wc.dg = /*extern(C)*/ delegate status_t (ubyte* data,
        uint length)
    {
        try
        {
            ostream.writeExact(data, length);
            return status_t.STATUS_SUCCESS;
        }
        catch (WriteException e)
        {
            ex = e;
            return status_t.STATUS_WRITE_ERROR;
        }
    };
    write_to_stream(m_surface_t, wc.write_func, wc.closure);
}

but it throws an AccessViolation when I call the "write_to_stream" function. I think it's probably missing the extern(C) but it doesn't compile with it. This is the code that calls the function.

Any pointers on how to implement this?

Thanks.
February 07, 2006
"Julio César Carrascal Urquijo" <jcesar@phreaker.net> wrote in message news:dsb2ih$30tt$1@digitaldaemon.com...
> Any pointers on how to implement this?

C simply doesn't support the calling convention that delegates used. Therefore, the only way to make it work is to use the inline assembler in C.


February 08, 2006
Walter Bright wrote:
> C simply doesn't support the calling convention that delegates used. Therefore, the only way to make it work is to use the inline assembler in C. 
> 


Never mind, got it working with a nested function.

Still, I would like to know how recommendable is to use a union to obtain the delegate's function pointer and stack frame?:

union WriteClosure
{
	extern(C) status_t delegate (ubyte* data, uint length) dg;
	struct
	{
		void* closure;
		write_func_t write_func;
	}
}

Seems to work on my PC but I worry that the order of the struct's members could change on another platform / compiler.

Thanks.
February 08, 2006
"Julio César Carrascal Urquijo" <jcesar@phreaker.net> wrote in message news:dsbmof$hgo$1@digitaldaemon.com...
> Still, I would like to know how recommendable is to use a union to obtain the delegate's function pointer and stack frame?:
>
> union WriteClosure
> {
> extern(C) status_t delegate (ubyte* data, uint length) dg;
> struct
> {
> void* closure;
> write_func_t write_func;
> }
> }
>
> Seems to work on my PC but I worry that the order of the struct's members could change on another platform / compiler.

It will change when, eventually, function pointers and delegates will become the same thing. That's a 2.0 thing, though.


February 09, 2006
Walter Bright wrote:
<snip>
> It will change when, eventually, function pointers and delegates will become the same thing. That's a 2.0 thing, though. 

The same thing?  I thought they were merely going to be convertible between each other.

Stewart.

-- 
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCS/M d- s:- C++@ a->--- UB@ P+ L E@ W++@ N+++ o K-@ w++@ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++>++++ h-- r-- !y
------END GEEK CODE BLOCK------

My e-mail is valid but not my primary mailbox.  Please keep replies on the 'group where everyone may benefit.
February 10, 2006
"Stewart Gordon" <smjg_1998@yahoo.com> wrote in message news:dsf4vb$1759$1@digitaldaemon.com...
> Walter Bright wrote:
> <snip>
>> It will change when, eventually, function pointers and delegates will become the same thing. That's a 2.0 thing, though.
>
> The same thing?  I thought they were merely going to be convertible between each other.

It's simpler if they just merge.


February 10, 2006
Walter Bright wrote:
> "Stewart Gordon" <smjg_1998@yahoo.com> wrote in message news:dsf4vb$1759$1@digitaldaemon.com...
>> Walter Bright wrote:
>> <snip>
>>> It will change when, eventually, function pointers and delegates will become the same thing. That's a 2.0 thing, though.
>> The same thing?  I thought they were merely going to be convertible between each other.
> 
> It's simpler if they just merge. 

But would it be near-enough as efficient?  I can see that it would bloat the runtime overhead of merely obtaining a delegate....

Stewart.

-- 
-----BEGIN GEEK CODE BLOCK-----
Version: 3.1
GCS/M d- s:- C++@ a->--- UB@ P+ L E@ W++@ N+++ o K-@ w++@ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++>++++ h-- r-- !y
------END GEEK CODE BLOCK------

My e-mail is valid but not my primary mailbox.  Please keep replies on the 'group where everyone may benefit.