You need to enable JavaScript to run this app. WinRT/C++结合wxWidgets初始化报错hresult_error如何解决
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 18:48:04