How to launch several instances of same plugin in same process?

Hi,
I tried to load the exact same VST3 plugin within my own VST3 host (as DLL) and during calling plugView->attached() the app locks up. I tested that exact scenario within another DAW, where the plugin works fine: 2 UI windows are opened there, but not in my own host yet.
In my own host the first instance is correctly launched on one thread and shows the UI (resizing, side chain, automation parameter, etc tests also succeed). The second instance runs on a separate thread (but within the same process).
When two different plugins are loaded this way, both show up correctly.
When loading the second plugin through IPC in a different process also anything works fine.
I tried to call InitDll only once (should it be called only once in this case?), but no difference.
Also I tried to use IPlugView* instead of IPtr<IPlugView> and
WindowController* _controller instead of WindowControllerPtr& controller;
with seemingly same result.

Do I need to modify this line:
PluginContextFactory::instance ().setPluginContext (&pluginContext);
when loading more than one instance ?
Vst::HostApplication pluginContext; is defined as in the editorhost sample

Loading 2 instances of another plugins work fine in this scenario also in my host with the current settings. That plugin also has a separate processor and controller component (as the tested plugin) And also tested with 2 instances of a single component plugin, which also works fine. But with loading the 4th different one as 2 instances it also fails.

Thank you.

VST3 relies on the “main thread” or “ui thread” concept, where most of the plug-in methods are called only on one and the same thread.
See vst-3-threading-model

Thank you very much for your answer, Arne.

By converting my own host code into a “UI thread”-based architecture, I encountered this problem:
Since each plugin instance (of the very same plugin) runs on the same UI thread,
within class ComponentHandler (inherited from Steinberg::Vst::IComponentHandler)
its no longer possible to determine the related audioclient-pointer by the thread id.
For example ComponentHandler::performEdit calls a global __stdcall function,
when then calls AudioServerClient::SetParameter(...)
(which is defined as: class AudioServerClient : public IMediaServer)
Then from there it calls AudioClient::setParameter(...), in a class AudioClient
inherited from IAudioClient, IMidiClient, IParameterClient.

How can I access the related instance ?

I tried this, which correctly compiles, but it does not work:

class PluginRuntimeInstance : public AudioLock
{
  public:
  	  static inline Steinberg::Vst::AudioServerClient* audioserverClient = NULL;	  
         // its "static inline" because otherwise compiler error  C2597
        // of course I don't want it static
	  // ...


	  class ComponentHandler : public Steinberg::Vst::IComponentHandler
	  {
	  public:

		  friend PluginRuntimeInstance;

		  ~ComponentHandler()
		  {
		  }

		  tresult PLUGIN_API beginEdit(ParamID id) override
		  {
			  return Steinberg::kResultOk;
		  }
		  tresult PLUGIN_API performEdit(ParamID id, ParamValue valueNormalized) override
		  {           
			  if (!PluginRuntimeInstance::audioserverClient) return Steinberg::kNotInitialized;
              // obtaining app->audioserverClient  from 
              //App* app = GetAppFromThread();  // not possible anymore
             // because they are now all on the same thread

              // here at least an instance-id or offset related to this instance,
              //  to pass the right  audioserverClient-pointer  :
			  int r = Steinberg::Vst::AudioServerClient_on_SetParameterInComponentHandler(
                           id, valueNormalized, 0 /*sampleOffset*/, 
                           PluginRuntimeInstance::audioserverClient);
			  return r;
		  }
		  tresult PLUGIN_API endEdit(ParamID id) override
		  {
			  return Steinberg::kResultOk;
		  }
		  tresult PLUGIN_API restartComponent(int32 flags) override
		  {
                   // same problem here!
			  return kNotImplemented; // yet
		  }

	  private:
		  tresult PLUGIN_API queryInterface(const TUID /*_iid*/, void** /*obj*/) override
		  {
			  return Steinberg::kNoInterface;
		  }
		  uint32 PLUGIN_API addRef() override { return 1000; }
		  uint32 PLUGIN_API release() override { return 1000; }

	  };

      ComponentHandler m_ComponentHandler;
};

=>

int AudioServerClient_on_SetParameterInComponentHandler(
                     ParamID id, ParamValue value, int32 sampleOffset, 
                     AudioServerClient* arg)
{
    // ..
	return  server_client->setParameter(id, value, sampleOffset);
}

=>

int __forceinline AudioServerClient::setParameter(ParamID id, ParamValue value, int32 sampleOffset)
{
    // ...
	client->setParameter(id, value, sampleOffset);
}

=>

void AudioClient::setParameter (ParamID id, ParamValue value, int32 sampleOffset)
{
	paramTransferrer.addChange (id, value, sampleOffset);
}

I think I figured it out: I added :

	public:
		Steinberg::Vst::AudioServerClient* audioserverClient = NULL;

in the class ComponentHandler
before calling setComponentHandler I set that audioserverClient pointer
and it seems to work now!

ComponentHandler* m_ComponentHandlerPtr = new (std::nothrow)ComponentHandler();
component_pointer = m_ComponentHandlerPtr;

if (m_ComponentHandlerPtr)
{
	m_ComponentHandlerPtr->audioserverClient = audioserverClient;
	App_editController->setComponentHandler(m_ComponentHandlerPtr);
}

So each component handler uses its local “audioserverClient” member, which is set right before “setComponentHandler”

Thank You!