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