是啥导致 Unity 3D 中的“WrongThreadException”?

Posted

技术标签:

【中文标题】是啥导致 Unity 3D 中的“WrongThreadException”?【英文标题】:What is causing the 'WrongThreadException' in Unity 3D?是什么导致 Unity 3D 中的“WrongThreadException”? 【发布时间】:2020-02-19 14:44:44 【问题描述】:

我想在 Unity 中集成一个 C++ 项目。 Unity 提供了一种称为I2CPP(C++ 的中间语言)的机制,它允许将 C++ 代码添加到您的统一项目中。我在 Visual Studio 的“空白应用程序(通用 Windows C++/CX)”项目中创建了一个简单的 C++ 类和标头。

// header
namespace SomeNamespace 
    public ref class MyRuntimeClass sealed
    
        public:
            // Constructor
            MyRuntimeClass();

            // Method to check if initialized
            bool IsClassInitialized();

        private:
            bool _isRuntimeInitialized = false;
    ;
 

// implementation
using SomeNamespace;
MyRuntimeClass::MyRuntimeClass()

    _isRuntimeInitialized = true;


bool MyRuntimeClass::IsClassInitialized()

    return _isRuntimeInitialized;
;

我在 Unity 中创建了一个简单的项目,并对文档中概述的播放器设置进行了必要的更改。我还添加了一个立方体作为游戏对象,并在立方体上附加了一个使用我的 C++ 代码的脚本,即

#if ENABLE_WINMD_SUPPORT
using SomeNamespace;
#endif

public class RuntimeSampleUnity : MonoBehaviour

#if ENABLE_WINMD_SUPPORT
    private MyRuntimeClass _myRuntimeClass;
#endif

    // Default MonoBehaviour method
    void Start()
    
#if ENABLE_WINMD_SUPPORT
        // New instance of runtime class
        _myRuntimeClass = new MyRuntimeClass();

        // Check to see if we initialized C++ runtime component
        var isInit = _myRuntimeClass.IsClassInitialized();
        Debug.LogFormat("MyRuntimeClass: 0", isInit);
#endif
    

在最后一步中,我已将 C++ 项目中的 winmd 文件添加到我在 Unity 中的资产中。该项目构建良好,但是当我运行该项目时,我得到一个Platform.WrongThreadException: The application called an interface that was marshalled for a different thread。是什么导致了这个异常(以及如何修复它)?

编辑:详细说明我为什么要做我正在做的事情:Microsoft 提供了一个project,它展示了如何将 OpenCV (C++) 集成到基于 HoloLens 的项目中。虽然它提供了一个混合了 OpenCV 和 C# 的 UWP 项目,但它没有展示如何将这个特定项目集成到 Unity 中。 Somebody actually made this possible via I2CPP。虽然我在使用他的基于 Visual Studio 2017 的项目进入 Visual Studio 2019 时遇到了问题,但我尝试制作一个最小的示例来了解它(基本上)是如何工作的。

【问题讨论】:

我没有听说它被用于将 c++ 添加到项目中 我认为 IL2CPP 只是将您的代码转换为 c++ 代码的编译器。我可能弄错了,但我认为这与 C++ 插件集成无关。在旁注中,无论谁投了反对票,你都会很好地解释原因。问题详细且相关。 您是在尝试运行构建的 exe,还是只是在编辑器中单击播放按钮? 我尝试构建一个可执行文件。我是通过“构建并运行”命令完成的。 你发布了整个代码吗?该异常的调用堆栈是什么?当您的 C++ 代码从错误的线程调用内容时,通常会引发该异常。这不太可能与 IL2CPP 有关。 【参考方案1】:

我认为你误解了 IL2CPP 的概念。

IL2CPP (Intermediate Language To C++) 是 Unity 开发的脚本 构建时可以用作 Mono 的替代方案的后端 各种平台的项目。使用 IL2CPP 构建项目时, Unity 将 IL 代码从脚本和程序集转换为 C++,之前 为您创建一个本地二进制文件(例如.exe、apk、.xap) 选择的平台。 IL2CPP 的一些用途包括增加 Unity 的性能、安全性和平台兼容性 项目。

要使用 C++,您必须编写 Native Plugin。

【讨论】:

根据我对文档的理解,您实际上可以使用 IL2CPP 添加外部 C++ 代码。从文档“使用 Windows 运行时支持直接从托管代码(脚本和 DLL)调用本机系统 Windows 运行时 API 以及自定义 .winmd 文件”。另请参阅上面在 HoloLens 项目中使用 OpenCV+Unity 的背景。

以上是关于是啥导致 Unity 3D 中的“WrongThreadException”?的主要内容,如果未能解决你的问题,请参考以下文章

Unity3D,为啥“脚本运行时版本”是 .NET3.5 而“api 兼容级别”是 .NET2.0? PlayerSettings 中的两个选项实际上是啥意思?

HLSL高级着色器语言怎样在unity3d只用,使用的步骤是啥

unity3d 插件是啥

unity3d的常用版本是啥

Unity3D是啥?好学么?一般要学习那些课程啊?

Unity3D中碰撞器和触发器的区别是啥啊?