WinRT/C++结合wxWidgets初始化报错hresult_error如何解决
WinRT/C++ 结合 wxWidgets 初始化失败解决方案
根本原因
wxWidgets Windows 平台版本在进入 MyApp::OnInit 生命周期前,已经自动为主线程初始化了单线程 COM 公寓(STA)。此时再调用 winrt::init_apartment() 会触发重复初始化 COM 环境的错误,对应的错误码通常为 0x80010106 (RPC_E_CHANGED_MODE)。
排查步骤
你可以通过捕获异常确认错误类型:
try { winrt::init_apartment(); } catch (winrt::hresult_error const& e) { std::wcout << L"错误码: " << std::hex << e.code() << L", 错误信息: " << e.message() << std::endl; }
解决方案
方案1:直接移除手动初始化代码(推荐)
wxWidgets 默认初始化的 STA 模式完全适配 WinRT/C++ 的默认运行要求,直接删除 winrt::init_apartment() 调用即可:
class MyApp : public wxApp { public: virtual bool OnInit(); }; IMPLEMENT_APP(MyApp) void blemain() { // 移除该行即可,无需重复初始化COM // winrt::init_apartment(); std::wcout << L"Main thread: " << std::this_thread::get_id() << std::endl; myfunc(); } bool MyApp::OnInit() { blemain(); return true; }
方案2:禁止wx自动初始化COM(适合需要自定义COM模式的场景)
如果你需要手动控制 WinRT 初始化的公寓类型(比如需要 MTA 模式),可以在 wx 初始化前关闭自动COM初始化功能,要求 wxWidgets 版本 >= 3.1.0:
class MyApp : public wxApp { public: MyApp() { // 关闭wx自动初始化COM的逻辑 SetCOMInitializerMode(wxCOMInitNone); } virtual bool OnInit(); }; IMPLEMENT_APP(MyApp) void blemain() { // 现在可以正常调用WinRT初始化 winrt::init_apartment(); std::wcout << L"Main thread: " << std::this_thread::get_id() << std::endl; myfunc(); } bool MyApp::OnInit() { blemain(); return true; }
注意事项
- 子线程中调用 WinRT 接口不受主线程初始化逻辑影响,仍需要在子线程执行逻辑开头单独调用
winrt::init_apartment() - 若使用低于 3.1.0 版本的 wxWidgets,没有
SetCOMInitializerMode接口,直接使用方案1即可正常运行
内容的提问来源于stack exchange,提问作者xikov
相关产品推荐
相关产品推荐

