如何扫描/枚举vst插件DLL?

如何扫描/枚举vst插件DLL?,dll,audio,vst,Dll,Audio,Vst,我正在尝试构建一个承载vst效果的小程序,我想扫描一个文件夹中的插件DLL。 我知道如何查找所有DLL,但现在我有以下问题: 确定给定dll是否为vst插件的最佳方法是什么? 我试着看看ddl是否导出了正确的函数,这对于使用最新版本的vst sdk制作的插件来说效果很好,因为它导出了一个名为“VstPluginMain”的方法,而旧版本则导出了一个相当通用的“main”函数 如何确定插件是效果还是工具 如何扫描vst外壳插件? Shell插件基本上是包含多种效果的DLL。Waves Audio

我正在尝试构建一个承载vst效果的小程序,我想扫描一个文件夹中的插件DLL。
我知道如何查找所有DLL,但现在我有以下问题:

  • 确定给定dll是否为vst插件的最佳方法是什么?
    我试着看看ddl是否导出了正确的函数,这对于使用最新版本的vst sdk制作的插件来说效果很好,因为它导出了一个名为“VstPluginMain”的方法,而旧版本则导出了一个相当通用的“main”函数
  • 如何确定插件是效果还是工具
  • 如何扫描vst外壳插件?
    Shell插件基本上是包含多种效果的DLL。Waves Audio制作的插件就是一个例子

ps:如果有一个库可以为我完成所有这些,请告诉我。

如何确定VST插件

一旦找到main/VSTPluginMain。。。叫它! 如果返回的内容为NULL,则它不是VST。 如果返回的是指向字节“VstP”的指针(请参见aeffect.h中的
VstInt32 magic;//
),则您有一个VST

VSTPluginMain返回指向AEffect结构的指针。你需要看看这个结构


效果还是工具
AEEffect::flags |(effFlagsIsSynth=1如果您想在.NET中开发您的VST主机应用程序,请看一看

@Dave Gamble解决了这个问题,但我想在VST外壳插件上添加一些东西,因为它们的使用有点棘手

要确定VST是否是外壳插件,请将
effGetPlugCategory
操作码发送给插件调度程序。如果它返回
kPlugCategShell
,则它是外壳插件。要获取外壳中的子插件列表,基本上调用
effShellGetNextPlugin
,直到它返回0。示例代码snipbit(改编自a):

如果你真的想在VST外壳中加载插件,那就有点麻烦了。首先,你的主机需要处理主机回调中的
audioMasterCurrentId
操作码。当你调用VST的
VSTPluginMain()时
方法来实例化插件,它将使用此操作码调用主机回调,并请求应加载的唯一ID


因为此回调是在主函数返回之前进行的(因此,在它向主机传递
AEffect*
之前),这意味着您可能需要将要加载的shell插件ID存储在一个全局变量中,因为您将无法在
AEffect
struct的
void*user
字段中保存指向任何有意义数据的指针,以便在主机回调中及时将其传回给您。

谢谢您的回答。这里只提供了一些在我没有完全得到。让我们假设我找到一个dll,它不是一个插件,而是导出“main”(这似乎是一个非常常见的名称…),然后从中返回一些东西。如果我尝试取消引用该值以查找“VstP”,我会不会遇到麻烦当然,你肯定会检查指针是否是非零的。你也可以考虑检查你的回调是否被调用。用户在他们的VSTPuxin文件夹中存储恶意的DLL是没有意义的。@ DaveGamble Yea,我主要关心的是恶意代码。好的答案!你愿意分享你的一些吗?主机代码?试图自己创建一个vst主机,不知道从哪里开始。@DanielRodrigues我有一个开源的vst主机
// All this stuff should probably be set up far earlier in your code...
// This assumes that you have already opened the plugin and called VSTPluginMain()
typedef VstIntPtr (*Vst2xPluginDispatcherFunc)(AEffect *effect, VstInt32 opCode, VstInt32 index, VstIntPtr value, void *ptr, float opt);
Vst2xPluginDispatcherFunc dispatcher;
AEffect* plugin;
char nameBuffer[40];

while(true) {
  memset(nameBuffer, 0, 40);
  VstInt32 shellPluginId = dispatcher(pluginHandle, effShellGetNextPlugin, 0, 0, nameBuffer, 0.0f);
  if(shellPluginId == 0 || nameBuffer[0] == '\0') {
    break;
  }
  else {
    // Do something with the name and ID
  }
}