You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity集成C++项目时出现WrongThreadException的原因及解决方法

Platform.WrongThreadException when accessing C++/CX WinMD from Unity via IL2CPP

Let's break down why you're hitting this error and how to fix it—since I've dealt with similar WinRT/Unity integration issues for HoloLens projects before, I know exactly where this comes from.

Background Context

First, let's align on your setup to make sure we're troubleshooting the right thing:

  • You built a minimal C++/CX WinRT component (MyRuntimeClass) in a UWP project
  • You imported the resulting .winmd into a Unity project configured for IL2CPP + UWP
  • Your Unity script creates and accesses the C++ class in the Start() method, but gets a cross-thread exception at runtime

Your Code Reference

Original C++ Header (SomeNamespace.h)

namespace SomeNamespace {
    public ref class MyRuntimeClass sealed {
    public:
        MyRuntimeClass();
        bool IsClassInitialized();
    private:
        bool _isRuntimeInitialized = false;
    };
}

C++ Implementation (SomeNamespace.cpp)

using namespace SomeNamespace;
MyRuntimeClass::MyRuntimeClass() {
    _isRuntimeInitialized = true;
}
bool MyRuntimeClass::IsClassInitialized() {
    return _isRuntimeInitialized;
};

Unity C# Script (RuntimeSampleUnity.cs)

#if ENABLE_WINMD_SUPPORT
using SomeNamespace;
#endif
public class RuntimeSampleUnity : MonoBehaviour {
    #if ENABLE_WINMD_SUPPORT
    private MyRuntimeClass _myRuntimeClass;
    #endif

    void Start() {
        #if ENABLE_WINMD_SUPPORT
        _myRuntimeClass = new MyRuntimeClass();
        var isInit = _myRuntimeClass.IsClassInitialized();
        Debug.LogFormat("MyRuntimeClass: {0}", isInit);
        #endif
    }
}

Why the Exception Happens

WinRT (and by extension C++/CX) components have thread affinity by default:

  • The default threading model for sealed C++/CX classes is STA (Single-Threaded Apartment). This means the object can only be accessed from the exact thread it was created on.
  • Unity's IL2CPP main thread runs in an MTA (Multi-Threaded Apartment) environment. When you create the MyRuntimeClass instance in Unity's Start() method (on the MTA thread), any subsequent access to its methods tries to cross thread contexts, triggering the WrongThreadException.

Fixing the Issue

The simplest and most robust fix for your use case (integrating non-UI C++ logic like OpenCV) is to modify your C++ class to support multi-threaded access:

Step 1: Update the C++ Class Threading Model

Add the Threading attribute to your class definition to allow access from both STA and MTA threads. You'll need to include the necessary WinRT metadata header first:

// Updated header with threading fix
#include <winrt/Windows.Foundation.Metadata.h>

namespace SomeNamespace {
    [Windows::Foundation::Metadata::Threading(Windows::Foundation::Metadata::ThreadingModel::Both)]
    public ref class MyRuntimeClass sealed {
    public:
        MyRuntimeClass();
        bool IsClassInitialized();
    private:
        bool _isRuntimeInitialized = false;
    };
}
  • ThreadingModel::Both tells the WinRT runtime that your class doesn't require thread affinity, so it can be accessed from any thread without marshaling.
  • This is safe for pure logic classes (like your OpenCV wrappers)—you only need to stick with STA if your class interacts with UI elements or other STA-bound WinRT components.

Step 2: Verify Unity Project Settings

Double-check these settings to ensure everything is configured correctly:

  • Go to Edit > Project Settings > Player > Windows
    • Set Scripting Backend to IL2CPP
    • Ensure Target SDK is set to a UWP version compatible with your HoloLens
    • Confirm Enable WinMD Support is checked

Additional Notes for HoloLens OpenCV Integration

Since you're migrating an OpenCV/HoloLens project, keep these in mind:

  • If your C++ code uses heavy computation, consider offloading it to a background thread (but make sure any WinRT objects used there also use ThreadingModel::Both).
  • Avoid accessing Unity's API from background threads—use UnityMainThreadDispatcher or similar patterns if you need to pass results back to Unity's main thread.

内容的提问来源于stack exchange,提问作者user1729210

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 16:42:43