我正在尝试在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没有声明它。对象删除还有另一个回调。
答案 0 :(得分:4)
Plugin
和Bleep
显然属于您将Bleep
新Plugin
分配给*
变量,而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将被清零以便使用它会导致段错误。
如果您真的想自己分配和解除分配对象,那么您应该使用free
和malloc
,尽管这肯定更复杂。您必须使用free
分配一个与对象大小相当的内存块,然后使用std.conv.emplace
在该内存块中构造该类以创建该对象。然后要释放它,你必须显式调用它的析构函数,然后在那个内存上调用alloc.new!MyClass(args)
。正在对自定义分配器进行工作,这绝对应该使这更容易(可能使它更接近alloc.free(obj)
和null
),但它们尚未完成,因此尚未达到标准库。
如果您不需要确定性破坏,使用GC处理分配和释放对象的一种方法是简单地在D代码中保留对象的引用,然后在您使用时将该引用设置为{{1}}想要释放这个对象。在GC决定收集它之前,它不会释放它,但它会使GC在你完成之前不会收集它,以便它能够在你完成之后收集它。
答案 1 :(得分:1)
只返回plugin
它已经是指针
只要您保留对它的引用,GC就不会声明它