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字节的核心原因是类布局不一致,可能的触发点:
- 编译选项不匹配:SDK静态库与项目的结构成员对齐选项(如MSVC的
/Zp参数)不同,导致类成员的内存偏移错位。 - Debug/Release模式混合:SDK和项目分别用Debug和Release模式编译,STL容器(如
std::string)的内部结构因调试宏(_ITERATOR_DEBUG_LEVEL)不同而大小变化。 - 预处理器宏差异:SDK和项目定义的宏不一致,导致
ClassInfo或其内部结构体存在条件编译的成员,改变了类的大小和布局。
解决方案
- 统一编译选项:
- 检查并确保SDK和项目的结构成员对齐设置完全一致(如MSVC中均设为
Default或相同的字节数)。 - 保证SDK与项目同为Debug或Release模式编译,禁止混合模式。
- 对比两者的预处理器宏,确保所有影响类布局的宏(如
_WIN32、_MSC_VER)完全一致。
- 检查并确保SDK和项目的结构成员对齐设置完全一致(如MSVC中均设为
- 修复非法的const_cast操作:
category()返回const std::string&,用const_cast修改属于未定义行为,应通过ci.get().category的方式修改成员。 - 调整SDK编译方式:将SDK从静态库改为动态库编译,或直接把SDK源码嵌入项目中编译,避免静态库的二进制兼容性问题。
- 检查ClassInfo定义:查看
ClassInfo的头文件,确认是否存在依赖宏的条件编译代码,确保SDK和项目中该类的结构完全一致。
内容的提问来源于stack exchange,提问作者Yuwei Xu
相关产品推荐
相关产品推荐

