Don't use STL smart pointers with VST3 interfaces

This would cause double frees since those objects are supposed to clean
up after themselves.
This commit is contained in:
Robbert van der Helm
2020-12-07 18:09:49 +01:00
parent 75e8cf9140
commit d79bc3b936
3 changed files with 13 additions and 11 deletions
+4 -1
View File
@@ -62,4 +62,7 @@ TODO: Explain how we implement `createInstance()`
- Since everything behind the scenes makes use of these `addRef()` and
`release()` reference counting functions, we can't use the standard library's
smart pointers when dealing with objects that are shared with the host or with
the Windows VST3 plugin.
the Windows VST3 plugin. In `IPtr<T>`'s destructor it will call release, and
the objects will clean themselfs up with a `delete this;` when the reference
count reaches 0. Combining this with the STL cmart pointers this would result
in a double free.
+5 -2
View File
@@ -86,7 +86,10 @@ Vst3PluginBridge::Vst3PluginBridge()
Steinberg::IPluginFactory* Vst3PluginBridge::get_plugin_factory() {
// Even though we're working with raw pointers here, we should pretend that
// we're `IPtr<Steinberg::IPluginFactory>` and do the reference counting
// ourselves because you can't always safely pass those around
// ourselves because you can't always safely pass those around The VST3
// interface can't pass smart pointers around because of binary
// compatibility, so we'll have to do the reference counting by hand like in
// the implementation in `public.sdk/source/main/pluginfactory.h`.
if (plugin_factory) {
plugin_factory->addRef();
} else {
@@ -94,7 +97,7 @@ Steinberg::IPluginFactory* Vst3PluginBridge::get_plugin_factory() {
// will request after loading the module. Host callback handlers should
// have started before this since the Wine plugin host will request a
// copy of the configuration during its initialization.
plugin_factory = std::make_unique<YaPluginFactoryPluginImpl>(*this);
plugin_factory = Steinberg::owned(new YaPluginFactoryPluginImpl(*this));
sockets.host_vst_control.receive_into(
WantsPluginFactory{}, *plugin_factory,
std::pair<Vst3Logger&, bool>(logger, true));
+4 -8
View File
@@ -80,15 +80,11 @@ class Vst3PluginBridge : PluginBridge<Vst3Sockets<std::jthread>> {
* Our plugin factory. All information about the plugin and its supported
* classes are copied directly from the Windows VST3 plugin's factory on the
* Wine side, and we'll provide an implementation that can send control
* messages to the Wine plugin host. Even though we're passign plain
* pointers around, we should pretend that they're wrapped in the VST3 SDK's
* reference counting p pointers so we should do the reference counting
* ourselves.
* messages to the Wine plugin host. The VST3 interface only passes raw
* pointers around and the receiving side should then use `IPtr<T>::adopt()`
* or `owned()` to get back the orignal smart pointer.
*
* @related get_plugin_factory
*
* FIXME: We can't use `std::unique_ptr` here because that breaks VST3's
* reference counting mechanism.
*/
std::unique_ptr<YaPluginFactory> plugin_factory;
Steinberg::IPtr<YaPluginFactory> plugin_factory;
};