This project has moved and is read-only. For the latest updates, please go here.

Loading Code and Framework assemblies from the VST DLL Folder

Jun 23, 2008 at 6:45 AM
Edited Jun 23, 2008 at 6:53 AM

This is a great work! I'm really please about this framework, as i want to developp some C# synth...
I'm working with Mark Heath, that manages the NAudio project on codeplex, and we would like in a near future to be able to plug your VST frameworks in order to 1) be able to act as a host and redirect VST processing to soundcard, and 2) be able to embed VST plugins for effects...

I have also a question / suggestion. I read that "The Jacobi.Vst.Core and Jacobi.Vst.Framework dlls should be installed in the Global Assembly Cache (GAC)".
Should it be possible to add a ResolveHandler in the Interop code so that these assemblies could be loaded from the same folder than the VST (in case they are not in the GAC)?
The reason is that sometimes, you don't want to install any assemblies on the GAC of the machine.

In a C# VST i did sometimes ago, i just added the following ugly code to load anykind of assembly from the same VST dll folder. It would be great to have such a feature

Thanks for your work. This project is going to be really helpful and open new perspectives for Audio .NET developpers!

Alexandre

//-------------------------------------------------------------------------------------------------------
static System::Reflection::Assembly^ MyResolveEventHandler( System::Object^ sender, System::ResolveEventArgs^ args ) {
    char fileName[MAX_PATH];
    char assemblyFileName[MAX_PATH];
    GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)&g_hInstance, &g_hInstance);
    DWORD nameSize = GetModuleFileName(g_hInstance,fileName,MAX_PATH);
    while (nameSize > 0 && fileName[nameSize] != '\\') {
        nameSize--;
    }

    cli::array<System::String^>^ assemblyNames = args->Name->Split(',');

    System::String^ assemblyFileNameStr = assemblyNames[0];
    assemblyFileNameStr += ".dll";

    // Convert Assembly Name to char and append directory
    const char* fileStr = (const char*)(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(assemblyFileNameStr)).ToPointer();
    assemblyFileName[0] = 0;
    int len = strlen(fileStr);
    strncpy(assemblyFileName,fileName,nameSize+1);
    strncpy(assemblyFileName + nameSize+1, fileStr, len);
    assemblyFileName[nameSize+1+len] = 0;
    // Do what you want with FileStr
    System::Runtime::InteropServices::Marshal::FreeHGlobal(System::IntPtr((void*)fileStr));
    
    assemblyFileNameStr = gcnew System::String((const char*)assemblyFileName);
    System::Reflection::Assembly^ loaded = System::Reflection::Assembly::LoadFile(assemblyFileNameStr);
    return loaded;
}

AudioEffect* createEffectInstance (audioMasterCallback audioMaster)
{

    System::AppDomain^ currentDomain = System::AppDomain::CurrentDomain;
    currentDomain->AssemblyResolve += gcnew System::ResolveEventHandler( MyResolveEventHandler );

    return new VstXSynth (audioMaster);
}
Jun 23, 2008 at 8:11 AM

Thanks!
Vst Host functionality is something I want to build later. The reason why I started this is because I need the plugin support for my own project(s). I also have a project on my todo list that would require a VST host and that would be the time for me to dive into vst host functionality. I have no experience in VST hosts and I sort of understand what they are supposed to do, but not enough to make decissions about code structure (interface defs and class hierarchies). I'm sorry for what must be a disappointing answer but my time is limited and otherwise I never get my project off the ground.

I think the default loading sequence of .NET of locating and loading assemblies is such that you don't need to do anything special to work with the Core and Framework assemblies in a local folder. The reason why I documented that these 'should' go into the GAC is for reuse: when you have mulitple plugins that all use the same version of VST.NET. So I make sure that these assemblies are strong-named and appropriatly versioned, just in case you do want to put them into the GAC. But I think you dont have to, although I have not tested it myself (yet). If this doesn't work by default I will consider your suggestion of resolving the assemblies manually.

Thanks for your support and I hope you will share any bugs or feature requests you might find/need. Go over to the Issue Tracker (next tab) to create items for bugs or feature requests and get people to vote on them. I aim to get all bugs out of the code - so one vote should be enough ;-).

Grtx,
Marc Jacobi

Jun 23, 2008 at 9:42 AM
>>Vst Host functionality is something I want to build later.
Supporting VST Plugin is much more important for now. VST Host will be a nice feature, but this is not currently a priority, so don’t worry, this is not a disappointing answer (i would better say encouraging). ;)

>> I think the default loading sequence of .NET of locating and loading assemblies is such that you don't need to do anything special to work with the Core and Framework assemblies in a local folder.
You are right… don’t know why I was not enable to have this default loading with my VSTNetPlugin… perhaps VST.NET doesn’t have this problem (I have to admit that I haven’t tested it yet, but I’ll do it very soon!)

Greetings,
Alexandre