Return an instance of a class as a pointer to D

I am trying to compile the following code to D

void* instantiate(_LV2_Descriptor* descriptor, 
  double sample_rate, char * bundle_path, 
  LV2_Feature** features) {
  Plugin plugin = new Bleep(sample_rate, features);
  return &plugin;
}

      

but i am getting the following error

../src/lv2/plugin.d(38): Error: escaping reference to local plugin

      

What is the correct way to instantiate a class and return it as a pointer? Also in such a way that it is not claimed by the GC. There is another callback for deleting the object.

+3


source to share


2 answers


Plugin

and Bleep

- these are obviously classes, given that you are assigning a new variable Bleep

to a variable Plugin

and there is no *

on declaration Plugin

. Thus, it Plugin

is a link, not a pointer. &plugin

returns a pointer to a reference - in this case - a local variable (hence an error). This is not what you want at all. You can explicitly specify Plugin

in void*

if you really want a pointer, but this is somewhat abnormal. I am assuming you are interacting with C code, otherwise there really should be no reason to throw onvoid*

... Class objects are references, not pointers, and should be left as such if possible. If you pass it to C code (presumably, which then call your D code later, since C doesn't know what to do with class D), then you are more or less stuck with using void*

, but I advise you to avoid it otherwise.

The GC will not release the object if your D code has a reference to it, but if you pass it to the C function and don't leave a reference to it in your D code, it will be collected at some point by the GC.

If you want to explicitly free the object yourself, then don't use GC. delete

is assigned to be deprecated, and you usually don't have to free things from the GC heap yourself. This is the job of the GC. You can call destroy

on an object to destroy it (for example destroy(obj);

), but the memory will not be freed (rather, the destructor will be called and the vtable will be zeroed out to allow it to segfault).



If you really want to allocate and free an object yourself, you should use malloc

and free

, although it's definitely more complicated. You will need to allocate a chunk of memory the size of the object using malloc

, and then use std.conv.emplace

to build a class in that chunk of memory to create the object. Then, to free it, you'll have to explicitly call its destructor and then call it free

in that memory. The work is done on custom allocators, which should make this easier (perhaps a lot closer to alloc.new!MyClass(args)

and alloc.free(obj)

), but they are not yet complete and so are not yet in the standard library.

One way to handle object allocation and deallocation using GC, if you don't need deterministic destruction, is to simply store a reference to the object in your D code, and then set that reference to null

when you want to free the object. It won't free it until the GC decides to collect it, but it does it so that the GC doesn't collect before you're done with it, so that it can collect it as soon as you do.

+4


source


just return plugin

, this is already a pointer



also as long as you keep a link to it it will not be declared by the GC

+1


source







All Articles