Я пытаюсь использовать утилиты VST-хостинга, включенные в SDK, для загрузки плагина. Код такой:
Код: Выделить всё
#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 vst_module = Module::create(vst3_module_path, error);
std::vector class_infos = vst_module->getFactory().classInfos();;
assert(error.empty());
assert(class_infos.size());
ClassInfo plugin_info = class_infos[0]; //Crash
//... load the plugin and do more things
return 0;
}
8
В моем случае SDK поставляется с исходными кодами и файлами cmake для сборки их в статическую библиотеку. Таким образом, мой код и код SDK используют один и тот же компилятор.
Исходники VST SDK от Steinberg Media
Расследование завершено:
Мое расследование показало, что PluginFactory::classInfos() возвращал поврежденные данные, попытка назначить из них вызывает std::bad_alloc, поскольку размер std:: строка недопустимо.
Определение PluginFactory::classInfos() в VST SDK:
Код: Выделить всё
PluginFactory::ClassInfos PluginFactory::classInfos () const noexcept
{
auto count = classCount ();
Optional factoryInfo;
ClassInfos classes;
classes.reserve (count);
auto f3 = Steinberg::FUnknownPtr (factory);
auto f2 = Steinberg::FUnknownPtr (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 (info ());
classInfo.get ().vendor = factoryInfo->vendor ();
}
}
return classes;
}
Войдя в конструктор std::string, я нашел указатель this во время строительства data.category НЕ равен &data.category и смещен на 4 байта.
Код: Выделить всё
&data.category = 0x 0000 009b 546f ed14
this (std::string constructor scope) = 0x 0000 009b 546f ed18
//Actual address varies but the offset remains the same
Дополнительная информация:
Эксперимент, связанный с std::string:
Кроме того, экспериментируя с ClassInfo и его строковыми элементами, я столкнулся с этим:
Код: Выделить всё
ClassInfo ci;
ci.get().category = "testCategory"; //OK
const_cast(ci.category()) = "testCategory"; //Crash, Access violation at 0xFFFFFFFFFFFFFFFF
Стандартная согласованность C++:
Я еще добавил
Код: Выделить всё
#if __cplusplus != 201703L
#error
#endif
Попытка воспроизведения:
Попытка воспроизведения:
h3>
Я надеялся воссоздать минимальный сценарий, в котором VST SDK не включен, и с моим собственным MimicClassInfo, который напоминает структуру исходного ClassInfo в некоторых аспектах. Проблема не возникает.
Информация о компиляторе и SDK:
MSVC 14.37.32822, с использованием C++ 17 стандарт.VST SDK 3.7.8, сборка 34 (15 мая 2023 г.)
Подробнее здесь: https://stackoverflow.com/questions/769 ... object-cau