StandalonePluginHolder* StandalonePluginHolder::getInstance() linker error

Can you move the implementation of StandalonePluginHolder* StandalonePluginHolder::getInstance() out of the header file and into a .cpp file?

That way I can include juce_StandaloneFilterWindow.h without getting linker errors. I need access to the AudioDeviceManager and this is the one way I can see to get it.

1 Like

I don’t think there is a cpp file that we could put it in - that class was designed to be header-only, and doesn’t really belong with any of the rest of the module cpps…

…but I’m unclear what linker errors you’re trying to avoid? Is there another way we could achieve the same thing?

I included juce_StandaloneFilterWindow.h in my project, so I could call StandalonePluginHolder::getInstance() so then I could get a pointer to the device manager.

However, if juce_StandaloneFilterWindow.h gets included twice, then there are two definitions of StandalonePluginHolder::getInstance() and linking fails.

I just moved the implementation of StandalonePluginHolder::getInstance() into the .cpp file that includes juce_StandaloneFilterWindow.h

Mango:juce rrabien$ git diff
diff --git a/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterApp.cpp b/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterApp.cpp
index 866c02a..f366172 100644
--- a/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterApp.cpp
+++ b/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterApp.cpp
@@ -48,7 +48,25 @@ extern juce::AudioProcessor* JUCE_CALLTYPE createPluginFilter();
 namespace juce
+StandalonePluginHolder* StandalonePluginHolder::getInstance()^M
+#if JucePlugin_Enable_IAA || JucePlugin_Build_Standalone^M
+    if (PluginHostType::getPluginLoadedAs() == AudioProcessor::wrapperType_Standalone)^M
+    {^M
+        auto& desktop = Desktop::getInstance();^M
+        const int numTopLevelWindows = desktop.getNumComponents();^M
+        ^M
+        for (int i = 0; i < numTopLevelWindows; ++i)^M
+            if (auto window = dynamic_cast<StandaloneFilterWindow*> (desktop.getComponent (i)))^M
+                return window->getPluginHolder();^M
+    }^M
+    ^M
+    return nullptr;^M
+    ^M
+    ^M
+    //==============================================================================^M
 class StandaloneFilterApp  : public JUCEApplication
diff --git a/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h b/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h
index f63884f..8a5a82c 100644
--- a/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h
+++ b/modules/juce_audio_plugin_client/Standalone/juce_StandaloneFilterWindow.h
@@ -832,21 +832,4 @@ private:
-StandalonePluginHolder* StandalonePluginHolder::getInstance()
-   #if JucePlugin_Enable_IAA || JucePlugin_Build_Standalone
-    if (PluginHostType::getPluginLoadedAs() == AudioProcessor::wrapperType_Standalone)
-    {
-        auto& desktop = Desktop::getInstance();
-        const int numTopLevelWindows = desktop.getNumComponents();
-        for (int i = 0; i < numTopLevelWindows; ++i)
-            if (auto window = dynamic_cast<StandaloneFilterWindow*> (desktop.getComponent (i)))
-                return window->getPluginHolder();
-    }
-   #endif
-    return nullptr;
 } // namespace juce

oh… well if it’s a double-inclusion, doesn’t it just work if you mark it ‘inline’?

That would work and be easier.