Delphi开发简易FX VST3宿主编辑器窗口崩溃问题咨询
问题分析与修复方案
核心错误根因
- 多次独立调用
CreateInstance创建不同接口实例:你当前为IComponent、IAudioProcessor、IEditController分别调用了三次插件工厂的创建方法,得到了三个完全独立的插件实例,不同实例之间无法通过IConnectionPoint连接,这是E_NOINTERFACE报错的主要原因 THostApplication接口实现不完整:QueryInterface未包含IHostApplication的IID判断,插件无法获取宿主的核心接口,会直接触发访问异常GetName未正确填充宿主名称返回,部分插件会校验该返回值CreateInstance返回成功但未赋值输出对象,插件调用该方法创建IMessage等实例时会拿到空指针,触发$18地址的AV错误
具体修复步骤
1. 修正插件实例创建逻辑
仅调用一次CreateInstance获取IComponent,其余接口通过QueryInterface查询:
// 仅调用一次CreateInstance创建插件实例 PluginFactory.CreateInstance(PANSIChar(@ClassInfo.cid), PANSIChar(@UID_IComponent), PluginInstance); Component := IComponent(PluginInstance); Component.SetIoMode(kSimple); HostApplication := THostApplication.Create; Error := Component.Initialize(HostApplication); // 直接从Component查询IAudioProcessor,不要重新创建实例 Component.QueryInterface(UID_IAudioProcessor, AudioProcessor); // 后续的AudioProcessor配置逻辑保留 // 从Component获取EditController,不要单独创建实例 Component.QueryInterface(UID_IEditController, EditController); // 或者调用Component.GetController方法获取,依你使用的VST3绑定实现为准 Error := EditController.Initialize(HostApplication);
2. 完善THostApplication实现
function THostApplication.QueryInterface(const IID: TGUID; out Obj): HResult; begin if (IID = UID_IPlugFrame) OR (IID = UID_FUnknown) OR (IID = UID_IHostApplication) then begin Pointer(Obj) := Self; _AddRef; // 注意要增加引用计数,避免对象提前释放 Result := kResultTrue; end else begin Result := E_NOINTERFACE; end; end; function THostApplication.GetName(name: PString128): TResult; var HostName: string; begin HostName := 'Delphi VST3 Host'; StringToWideChar(HostName, PWideChar(name), 127); Result := kResultOk; end; function THostApplication.CreateInstance(cid, iid: TUID; var obj: pointer): TResult; begin obj := nil; Result := E_NOTIMPL; // 未实现的话返回明确错误,不要返回成功 end;
3. 校验IConnectionPointGUID定义
核对你使用的Delphi VST3绑定中UID_IConnectionPoint的定义是否和官方SDK一致,官方IID为{5503B854-413B-42A2-A559-1519198A2C43},定义错误会直接导致E_NOINTERFACE报错。
4. 完成组件连接与状态同步
HRes := Component.QueryInterface(UID_IConnectionPoint, cp_comp); if HRes = kResultOk then begin HRes := EditController.QueryInterface(UID_IConnectionPoint, cp_edit); if HRes = kResultOk then begin cp_comp.Connect(cp_edit); cp_edit.Connect(cp_comp); // 同步组件状态到控制器 // 这里需要你实现符合VST3规范的IStream流对象,传递Component的状态到EditController // 完成后再调用CreateView创建编辑器 end; end;
FX VST3通用使用流程
- 初始化阶段:加载插件DLL→调用
InitDLL→获取插件工厂→枚举插件类→创建IComponent实例→传入宿主接口初始化组件→查询IAudioProcessor→配置总线布局、采样率、块大小等参数→获取并初始化IEditController→连接两者的IConnectionPoint→同步组件状态到控制器 - 音频处理阶段:调用
SetProcessing(True)启动处理→循环传入包含输入输出缓冲区的ProcessData结构获取处理后的音频→处理结束调用SetProcessing(False) - 编辑器管理:调用
EditController.CreateView(kEditor)获取视图→设置PlugFrame→将视图绑定到宿主窗口句柄→实现ResizeView回调适配窗口大小→关闭时调用PlugView.Removed()释放视图 - 资源释放:断开连接点连接→调用组件的
Terminate方法→释放所有接口引用→调用ExitDLL→卸载DLL
内容的提问来源于stack exchange,提问作者3delite
相关产品推荐
相关产品推荐

