Get Path to resources folder

How do I get the path to my plugin resources folder in my C++ code ?
For instance in the below code how do I get the resourcePath ?

std::string audioSamplePath = resourcePath + “samples/sample1.wav”;

Assuming you are talking about the path to the resources folder inside of your plugin bundle: you need to use the function call appropriate to your OS that will return the path to your DLL (plugin’s main module). With that, you would then need to do some string or path manipulation to find the the resources folder. For Windows, that will involve GetModuleFileName( ) and on MacOS, it will involve CFBundleGetBundleWithIdentifier( ), and CFURLCopyFileSystemPath( ) at a minimum.

EDIT: sorry but I had my all-API hat on. For VST3, there is a path variable declared as a global variable in both macmain.cpp (MacOS) and dllmain.cpp (Windows). Those global char arrays are initialized when the DLL loads.

char gPath[VST_MAX_PATH]

So, you could declare an extern char * gPath; and then grab the value in the initialize( ) function.

As long as those global variables remain in subsequent SDKs, and with the same name, and you are OK with depending on that, then it should be good. If not, there are ways to get that information from scratch (above OS calls).

2 Likes

thanks that worked.
regards

Can you shed some more light on how this works for Xcode? Maybe some code snippet how to get the path from processor.cpp?

It’s a bit unclear how macmain.cpp is integrated - it is part of the public.sdk and it sounds strange to edit the VST3 sources just to get the path? macmain.cpp is included in each Xcode project created with the VST3_Project_Generator.app - so editing it inside a project will have an effect on all other projects, too.

At least, from debugger it’s clear to see that the gPath variable is set, but it sounds a bit hackish to make it a global.

Here is a little code snippet that gets the absolute path to the VST plugin on Mac OS. From there, you only need to append “/Contents/Resources/” to get the content in a resources folder:

static std::string GetPathToVST3Plugin() {
    // See https://developer.apple.com/library/archive/documentation/CoreFoundation/Conceptual/CFBundles/AccessingaBundlesContents/AccessingaBundlesContents.html
    CFBundleRef mainBundle = GetCurrentBundle ();
    if (mainBundle)
    {
        CFURLRef tempURL = CFBundleCopyBundleURL (mainBundle);
        char path[2048] = {0};
        CFURLGetFileSystemRepresentation (tempURL, true, (UInt8*)path, 2048);
        CFRelease (tempURL);
        return path;
    }
    return "Path/Not/Found";
}

Execute this like this:

    std::string path = GetPathToVST3Plugin();
    printf("%s", path.c_str());

In order to make it work independently of the current VST SDK, you also need to copy these helper functions from basewrapper.cpp:

#include <CoreFoundation/CoreFoundation.h>
#include <dlfcn.h>

...

// See public.sdk/source/vst/vst2wrapper/basewrapper.cpp
static CFBundleRef GetBundleFromExecutable (const char* filepath)
{
   char* fname = strdup (filepath);
   int pos = strlen (fname);
   int level = 3;
   while (level > 0 && --pos >= 0)
   {
       if (fname[pos] == '/')
           level--;
   }
   if (level > 0)
       return 0;

   fname[pos] = 0;
   CFURLRef url = CFURLCreateFromFileSystemRepresentation (0, (const UInt8*)fname, pos, true);
   CFBundleRef bundle = CFBundleCreate (0, url);
   return bundle;
}

static CFBundleRef GetCurrentBundle ()
{
   Dl_info info;
   if (dladdr ((const void*)GetCurrentBundle, &info))
   {
       if (info.dli_fname)
       {
           return GetBundleFromExecutable (info.dli_fname);
       }
   }
   return 0;
}

Note that the same code is also executed to run the functions defined in macmain.cpp, so it should give the same results. I suppose there must be an easier way to achieve such a common thing, but haven’t found one yet.

1 Like