返回一个类实例作为D中的指针

时间:2012-03-31 15:00:06

标签: d

我正在尝试在D

中编译以下代码
void* instantiate(_LV2_Descriptor* descriptor, 
  double sample_rate, char * bundle_path, 
  LV2_Feature** features) {
  Plugin plugin = new Bleep(sample_rate, features);
  return &plugin;
}

但是我收到以下错误

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

创建类实例并将其作为指针返回的正确方法是什么?也是这样,GC没有声明它。对象删除还有另一个回调。

2 个答案:

答案 0 :(得分:4)

PluginBleep显然属于您将BleepPlugin分配给*变量,而plugin上没有plugin的{​​{1}} 1}}的声明。因此,&plugin是引用,而不是指针。 plugin返回一个指向引用的指针 - 在这种情况下,它是一个局部变量(因此是错误)。这根本不是你想要的。如果你真的想要一个指针,你可以显式地将void*转换为void*,但 是一个有点不正常的事情。我假设你正在与C代码接口,否则真的应该没有理由投射到void*。类对象是引用,而不是指针,如果可能,应该保留。如果你把它传递给C代码(可能会稍后调用你的D代码,因为C不知道如何处理D类),那么你或多或少地使用delete,但我建议不要这样做。

只要您的D代码对它有引用,GC就不会释放该对象,但是如果您将它传递给C函数并且不在D代码中留下任何引用,它将在某些时候由GC收集

如果您要自己明确释放该对象,请不要使用GC。 destroy计划弃用,你通常不应该自己在GC堆上释放东西。这是GC的工作。你可以在一个对象上调用destroy(obj);来销毁它(例如malloc),但是不会释放内存(而是会调用析构函数,并且对象的vtable将被清零以便使用它会导致段错误。

如果您真的想自己分配和解除分配对象,那么您应该使用freemalloc,尽管这肯定更复杂。您必须使用free分配一个与对象大小相当的内存块,然后使用std.conv.emplace在该内存块中构造该类以创建该对象。然后要释放它,你必须显式调用它的析构函数,然后在那个内存上调用alloc.new!MyClass(args)。正在对自定义分配器进行工作,这绝对应该使这更容易(可能使它更接近alloc.free(obj)null),但它们尚未完成,因此尚未达到标准库。

如果您不需要确定性破坏,使用GC处理分配和释放对象的一种方法是简单地在D代码中保留对象的引用,然后在您使用时将该引用设置为{{1}}想要释放这个对象。在GC决定收集它之前,它不会释放它,但它会使GC在你完成之前不会收集它,以便它能够在你完成之后收集它。

答案 1 :(得分:1)

只返回plugin它已经是指针

只要您保留对它的引用,GC就不会声明它