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

Unity C#脚本调用WinRT组件构造函数触发NullReferenceException排查

问题描述

我正在开发一个基于C++/WinRT组件的Unity插件,在Unity C#脚本中尝试访问运行时类时抛出了NullReferenceException。以下是简化后的组件及Unity脚本代码:

WinRT RTClass.idl

namespace RuntimeComponent1
{
    runtimeclass HelperClass
    {
        HelperClass();
        Int32 MyProperty;
    }

    [default_interface]
    runtimeclass RTClass
    {
        RTClass();
        Int32 MyProperty;
    }
}

WinRT HelperClass.h

#pragma once
#include "HelperClass.g.h"

namespace winrt::RuntimeComponent1::implementation
{
    struct HelperClass: HelperClassT<HelperClass>
    {
        HelperClass();

        int32_t MyProperty();
        void MyProperty(int32_t value);
    };
}

namespace winrt::RuntimeComponent1::factory_implementation
{
    struct HelperClass: HelperClassT<HelperClass, implementation::HelperClass>
    {
    };
}

WinRT RTClass.h

#pragma once
#include "RTClass.g.h"

namespace winrt::RuntimeComponent1::implementation
{
    struct RTClass : RTClassT<RTClass>
    {
        RTClass();

        int32_t MyProperty();
        void MyProperty(int32_t value);
    };
}

namespace winrt::RuntimeComponent1::factory_implementation
{
    struct RTClass : RTClassT<RTClass, implementation::RTClass>
    {
    };
}

WinRT HelperClass.cpp

#include "pch.h"
#include "HelperClass.h"
#include "HelperClass.g.cpp"

namespace winrt::RuntimeComponent1::implementation
{
    HelperClass::HelperClass()
    {
    }
    int32_t HelperClass::MyProperty()
    {
        throw hresult_not_implemented();
    }

    void HelperClass::MyProperty(int32_t /* value */)
    {
        throw hresult_not_implemented();
    }
}

WinRT RTClass.cpp

#include "pch.h"
#include "RTClass.h"
#include "RTClass.g.cpp"

namespace winrt::RuntimeComponent1::implementation
{
    RTClass::RTClass()
    {
    // Do some stuff in the constructor
    }
    int32_t RTClass::MyProperty()
    {
        throw hresult_not_implemented();
    }

    void RTClass::MyProperty(int32_t /* value */)
    {
        throw hresult_not_implemented();
    }
}

Unity脚本

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

#if ENABLE_WINMD_SUPPORT
using RuntimeComponent1;
#endif

public class TestScript : MonoBehaviour
{
#if ENABLE_WINMD_SUPPORT
RTClass rt;
#endif

    // Start is called before the first frame update
    void Start()
    {
        #if ENABLE_WINMD_SUPPORT
    rt = new RTClass(); // <--- NullReferenceException here
    // ...
        #endif
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

相关环境与配置:

  • WinRT组件以Debug模式针对ARM架构构建
  • Unity版本:2021.3.27f1 LTS、2022.3.3f1 LTS
  • Unity配置:已将.dll和.winmd文件复制到Assets\Plugins\WSA\ARM路径,Platform Settings>CPU设为ARM;Player Settings中允许Unsafe Code,Api兼容性级别设为.NET Framework,构建平台为UWP,架构为ARM
  • 脚本智能感知无报错,Unity编译成功,仅运行时抛出异常,推测问题出在WinRT组件侧,询问可能的原因。
可能的原因及解决方向
  • 组件未正确注册:UWP环境下WinRT组件需要完成注册才能被调用。Debug模式构建的组件可能未在测试设备/模拟器上完成注册,导致无法实例化类。可尝试先将组件部署到目标设备,再运行Unity项目;或改用Release模式构建组件(Release模式会自动处理部分注册逻辑)。
  • 类工厂生成异常:虽然代码中定义了factory_implementation下的RTClass,但C++/WinRT的代码生成可能出现问题,导致类工厂未正确导出。检查生成的RTClass.g.cpp文件,确认类工厂的注册代码是否存在;也可清理项目后重新构建组件,触发代码重新生成。
  • ARM架构兼容性问题:Debug模式下的ARM构建可能存在未处理的架构相关问题,比如指针大小不匹配、原生指令兼容问题。可尝试切换到ARM64架构构建组件和Unity项目,或检查组件代码中是否有依赖特定架构的未兼容逻辑。
  • 构造函数内部异常:RTClass构造函数中的实际代码(注释部分// Do some stuff in the constructor)如果包含抛出异常的逻辑,可能导致实例化失败,WinRT异常在C#侧可能被包装为NullReferenceException。可暂时注释掉构造函数内的所有代码,测试是否能正常实例化。
  • WinMD文件不完整或版本不匹配:复制到Unity的.winmd文件可能未正确包含RTClass的类型信息,或与.dll文件版本不一致。重新构建WinRT组件,确保复制最新生成的.winmd和.dll文件到Unity的Plugins目录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 13:27:03