You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VST3 SDK中ClassInfo的std::string构造异常致程序崩溃求助

VST3 SDK加载插件时ClassInfo赋值崩溃问题

问题现象

使用VST3 SDK宿主工具加载插件时,执行ClassInfo plugin_info = class_infos[0];语句触发崩溃,原因是std::string成员大小无效导致std::bad_alloc异常。

重现代码

#include "vst/v3/Vst3CommonIncludes.h"

int main()
{
    std::string vst3_module_path = R"(C:\Program Files\Common Files\VST3\Kontakt.vst3)";
    std::string error;
    std::shared_ptr<Module> vst_module = Module::create(vst3_module_path, error);
    std::vector<ClassInfo> class_infos = vst_module->getFactory().classInfos();;

    assert(error.empty());
    assert(class_infos.size());

    ClassInfo plugin_info = class_infos[0]; // Crash here
    //... load the plugin and do more things
    return 0;
}

注:Vst3CommonIncludes.h包含pluginterfaces/vst和public.sdk/source/vst下的所有VST SDK头文件,SDK以源码形式通过CMake编译为静态库,与当前代码使用同一编译器。

排查细节

调试发现PluginFactory::classInfos()返回的ClassInfo对象存在内存损坏:

  • ClassInfo::data::category等std::string成员在调试器中显示为<NULL>
  • 进入std::string构造函数时,data.category的地址与构造函数中的this指针偏移4字节,导致字符串对象结构破坏

以下是SDK中PluginFactory::classInfos()的实现:

PluginFactory::ClassInfos PluginFactory::classInfos () const noexcept
{
    auto count = classCount ();
    Optional<FactoryInfo> factoryInfo;
    ClassInfos classes;
    classes.reserve (count);
    auto f3 = Steinberg::FUnknownPtr<Steinberg::IPluginFactory3> (factory);
    auto f2 = Steinberg::FUnknownPtr<Steinberg::IPluginFactory2> (factory);
    Steinberg::PClassInfo ci;
    Steinberg::PClassInfo2 ci2;
    Steinberg::PClassInfoW ci3;
    for (uint32_t i = 0; i < count; ++i)
    {
        if (f3 && f3->getClassInfoUnicode (i, &ci3) == Steinberg::kResultTrue)
//------------Unexpected behaviour here--------------------
            classes.emplace_back (ci3);                //--
//---------------------------------------------------------
        else if (f2 && f2->getClassInfo2 (i, &ci2) == Steinberg::kResultTrue)
            classes.emplace_back (ci2);
        else if (factory->getClassInfo (i, &ci) == Steinberg::kResultTrue)
            classes.emplace_back (ci);
        auto& classInfo = classes.back ();
        if (classInfo.vendor ().empty ())
        {
            if (!factoryInfo)
                factoryInfo = Optional<FactoryInfo> (info ());
            classInfo.get ().vendor = factoryInfo->vendor ();
        }
    }
    return classes;
}

附加测试结果

  • 直接修改ClassInfo的成员正常,但通过const_cast修改category()返回的引用会崩溃:
    ClassInfo ci;
    ci.get().category = "testCategory";                  // OK
    const_cast<string&>(ci.category()) = "testCategory"; // Crash, Access violation at 0xFFFFFFFFFFFFFFFF
    
  • 已通过预编译宏校验,确认代码与SDK均使用C++17标准及同一STL实现:
    #if __cplusplus != 201703L
    #error
    #endif
    
  • 模拟MimicClassInfo场景未复现问题,排除代码逻辑本身的错误。

环境信息

  • MSVC 14.37.32822
  • C++17标准
  • VST3 SDK 3.7.8 build 34(2023-05-15)

原因分析与解决方案

原因分析

内存地址偏移4字节的核心原因是类布局不一致,可能的触发点:

  1. 编译选项不匹配:SDK静态库与项目的结构成员对齐选项(如MSVC的/Zp参数)不同,导致类成员的内存偏移错位。
  2. Debug/Release模式混合:SDK和项目分别用Debug和Release模式编译,STL容器(如std::string)的内部结构因调试宏(_ITERATOR_DEBUG_LEVEL)不同而大小变化。
  3. 预处理器宏差异:SDK和项目定义的宏不一致,导致ClassInfo或其内部结构体存在条件编译的成员,改变了类的大小和布局。

解决方案

  1. 统一编译选项:
    • 检查并确保SDK和项目的结构成员对齐设置完全一致(如MSVC中均设为Default或相同的字节数)。
    • 保证SDK与项目同为Debug或Release模式编译,禁止混合模式。
    • 对比两者的预处理器宏,确保所有影响类布局的宏(如_WIN32、_MSC_VER)完全一致。
  2. 修复非法的const_cast操作:category()返回const std::string&,用const_cast修改属于未定义行为,应通过ci.get().category的方式修改成员。
  3. 调整SDK编译方式:将SDK从静态库改为动态库编译,或直接把SDK源码嵌入项目中编译,避免静态库的二进制兼容性问题。
  4. 检查ClassInfo定义:查看ClassInfo的头文件,确认是否存在依赖宏的条件编译代码,确保SDK和项目中该类的结构完全一致。

内容的提问来源于stack exchange,提问作者Yuwei Xu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 15:27:03