Allocating delegate on heap?

Kirk McDonald kirklin.mcdonald at gmail.com
Mon Feb 19 03:46:28 PST 2007


Rick Mann wrote:
> It appears that a delegate can't be directly allocated on the heap; only as part of a struct, class or array. This is rather annoying.
> 
> I'm trying to wrap a C api for event handling (on Mac OS X). In it, you register event handlers as C-linkage callback functions, and you register a bit of "user data" (4 bytes, usually a pointer to something). In your callback, the user data used when you registered is provided, and you typically cast it to your struct or class or whatever.
> 
> I'd like to use a delegate as my user data, but it's 8 bytes. So I need to pass a pointer to the delegate, and I need the delegate to live longer than the scope of the code that registered the callback in the first place. However, I don't see how to create a delegate on the heap. Is there any way? (Other than to wrap it in some clunky struct?)
> 
> TIA,
> Rick

[test.d]
import std.stdio;

void main() {
     auto dg = new void delegate();
}

$ dmd test.d
test.d(4): Error: new can only create structs, dynamic arrays or class 
objects, not void delegate()'s

No, you can't place delegates on the heap. I'm afraid you're stuck with 
using a struct.

However, there's a very important detail which you should not overlook: 
You are passing a pointer to GC-controlled data to a C library. The D 
garbage collector doesn't scan the C library for references, so you will 
need to keep a reference to any structs you pass to Carbon in your D 
code. Otherwise, the GC will feel free to collect them when you least 
expect it. This can be done with an AA:

struct DelegateStruct {
     void delegate() dg;
}

bool[DelegateStruct*] references;

DelegateStruct* get_ref(void delegate() dg) {
     auto s = new DelegateStruct;
     references[s] = true;
     s.dg = dg;
     return s;
}

void drop_ref(DelegateStruct* s) {
     references.remove(s);
}

-- 
Kirk McDonald
http://kirkmcdonald.blogspot.com
Pyd: Connecting D and Python
http://pyd.dsource.org


More information about the Digitalmars-d-learn mailing list