Plugin directory

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

I wrote a simple loader .dll, which only exports vstpluginmain/main, and when loaded, loads another plugin dll, calls its vstpluginmain /main and passes its return back to host, which then communicates directly with the plugin.
Thus, the dll loaded/scanned by the host can have any name, while leaving the plugin name untouched.

It works for every plugin dll, despite symptohm PE.

Symptohm PE needs to load a libsndfile-1.dll, which is located beneath the symptohm dll folder. When the host now loads my loader dll, which in return loads symptohm PE, the symptohm cannot find the libsndfile-1.dll and crashes. If I duplicate the folder structure of the symptohm PE dll beneath my loader dll and duplicate the libsndfile-1.dll, then it worked.

How can I prevent this? How does a vst plugin know its dll directory? And how can I change/specify this within my loader dll, so that symptohm searches in its own folder structure when loaded by the loader dll?

Post

SetCurrentDirectory() to the loaded PlugIn's path before loading it

... oh, and change it back after having loaded the thing (for hosts that don't expect such behavior)
"Until you spread your wings, you'll have no idea how far you can walk." Image

Post

So there's no VST call to set a Plugin directory...?

Ok, I guess I'll have to reset the currentdirectory after loading to where it was before calling? Changing the currdir when just loading a dll isn't that proper coding, is it?

Post

That's what I said.

BTW, regarding "How does a vst plugin know its dll directory?" - dead easy in Windows, but maybe not so easy for PlugIns that start at a higher level (SynthEdit, for example).

"Where am I?", VST 2.4-style:

Code: Select all

extern void* hInstance;  // declared and set in vstplugmain.cpp
...
char buffer[_MAX_PATH];
GetModuleFileName((HMODULE)hInstance, buffer, sizeof(buffer));
// knowing who we are, let's reduce that to just the directory part:
*strrchr(buffer, '\\') = '\0';
[Edit: added file name removal]

But you'll meet many PlugIns written by people who only know the barest necessities about the environment they want to get their stuff running in. These will start looking for their files in the current directory.
Last edited by arakula on Tue Jul 03, 2012 9:37 am, edited 2 times in total.
"Until you spread your wings, you'll have no idea how far you can walk." Image

Post

Thank you! :)

Post

Hmm... That did not help...

Loading the symptohm dll x64 in vsthost x64 works.
Loading the x64 loader dll, which changes currdir and loads symptohm x64 does not work, until I copy the libsndfile-1.dll in the same subfolder under the loader parent dir, as it is under the symptohm parent dir...

What can this be?


AddDllDirectory?
Does loadLibrary search recursively?

Post

Since you say VSTHost works -

VSTHost does the following (reduced to your problem):
  • SetCurrentDirectory() to the PlugIn's path
  • load PlugIn
  • call PlugIn's VstPluginMain / main to let it initialize
  • change back to original current directory
"Until you spread your wings, you'll have no idea how far you can walk." Image

Post

Ah, ok, thanks for this information, I reset currdir immediately after loadlibrary... Will try resetting currdir after vstpluginmain...

Thanks for your help!

Post

strange, this didn't work, too...

I put a messagebox before setting the currentdir and call to VSTPluginMain, and a Messagebox after returning from VSTPluginMain and before resetting the currentdir...

SymptohmPE is the only plugin which doesn't return from its VSTPluginMain... there is no second MessageBox...

how can this be?

What are you doing in addition, to have the plugin loaded correctly?

Post

Most plugins, in VSTPluginMain, will start sending you calls through the audioMaster function. Sometimes the return value from one of these calls causes the plugin to fail.

So, add breakpoints in your audioMaster function to check which opcodes are called from VSTPluginMain, because what you return in one of these opcodes is probably what causes SymptohmPE to hang.

Post

I don't use a audiomaster callback ;)

I simply implemented a VSTPluginMain. When called it loadlibrary the plugin dll, then call that plugins VSTPluginMain, passes it the parameters my VSTPluginMain gets from the host, and returns that plugins VSTPluginMains return parameter to the host.

So, the plugin actually communicates allways with host, and never with the loader DLL...


It's strange, it works with every plugin but symptohmPE.

And symptohmPE works even when loaded via jBridge, but not via my loader...

Post

and symptohmPE loads fine when loaded directly from the same host ?

Post

yes, it does...

This is the loader DLL... no magic... ;)

in VSTPluginMain, I read the first line of an equally named .txt file, which contains the path to the plugin dll to be loaded.

Code: Select all

#include "windows.h"
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>

using namespace std;

struct AEffect;

typedef void* audioMasterCallback;
typedef AEffect* (*PluginVSTPluginMain)(audioMasterCallback);

HINSTANCE			hThis;
HINSTANCE			hPlugin;

// --------------------VSTPluginMain -------------------------------------------------
extern "C" __declspec(dllexport) BOOL isVST2PluginManagerLoader() {
	return true;
}

// --------------------VSTPluginMain -------------------------------------------------
extern "C" __declspec(dllexport) AEffect* VSTPluginMain(audioMasterCallback audioMaster)
{
	TCHAR				szFileName[_MAX_PATH];
	string				strFileName;
	string				strLine;
	ifstream			isFile;
	PluginVSTPluginMain	pPluginVSTPluginMain;

	// FilePath of this dll
	GetModuleFileName(hThis, szFileName, _MAX_PATH);
	// append file extension ".txt"
	strFileName = szFileName;
	strFileName = strFileName.substr(0, strFileName.find_last_of(".") ) + ".txt";
	// read txt file, retrieve plugin dll filename
	isFile.open(strFileName);
	getline(isFile,strLine);
	// crop leading/trailing quota, if present
	strLine = strLine.substr(strLine.find_first_of("\"") + 1, strLine.find_last_of("\"") - 1 );
	strcpy_s (szFileName, strLine.c_str());
	isFile.close();
        // load the plugin dll
	hPlugin = LoadLibraryEx(szFileName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
	if (!hPlugin) return FALSE;
	// get the adress of the plugins main entry
	pPluginVSTPluginMain = (PluginVSTPluginMain) GetProcAddress(hPlugin, "VSTPluginMain");
	if (!pPluginVSTPluginMain) pPluginVSTPluginMain = (PluginVSTPluginMain) GetProcAddress(hPlugin, "main");
	if (!pPluginVSTPluginMain) return FALSE;
	return ((AEffect *(*)(audioMasterCallback))pPluginVSTPluginMain) (audioMaster);
}

// --------------------DllMain -------------------------------------------------------
//extern "C" BOOL __declspec(dllexport) WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
	hThis = hinstDLL;

	switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
	    //attach to process
            break;

        case DLL_PROCESS_DETACH:
            // detach from process
            break;

        case DLL_THREAD_ATTACH:
            // attach to thread
            break;

        case DLL_THREAD_DETACH:
            // detach from thread
            break;
    }
    return TRUE; // succesful
}
I tried using SetCurrentDirectory before calling the loadewd DLLs VSTPluginMain to set thge CurrDir to that plugins parent Dir, and reset the CurrentDir back to where it was before calling... Did not help...

Post

SetDllDirectory did not help either...

I'm clueless...

Post

You didn't show the SetCurrentDirectory-related code, but I'm sure you checked it.

In that case, you should also intercept the audio master callback function. There's a call with the opcode audioMasterGetDirectory that a PlugIn can use to get its base directory. VSTHost would return the loaded PlugIn's (=your PlugIn's) directory here.
"Until you spread your wings, you'll have no idea how far you can walk." Image

Post Reply

Return to “DSP and Plugin Development”