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

.NET7传递UDT类型SAFEARRAY至COM函数时触发TLBX_E_LIBNOTREGISTERED异常原因

.NET 7调用COM传递UDT类型SAFEARRAY时的COMException异常问题

异常详情

System.Runtime.InteropServices.COMException
HResult=0x80131165
Message=Typelib export: Type library is not registered. (0x80131165)
Source=System.Private.CoreLib
StackTrace:
at System.StubHelpers.MngdSafeArrayMarshaler.ConvertSpaceToNative(IntPtr pMarshalState, Object& pManagedHome, IntPtr pNativeHome)
at IServer.ComputePi(ExampleStruct[] param)
at ManagedClient.Program.Main(String[] _)

异常场景特征

  • 仅在.NET 7环境下触发,.NET Framework或原生客户端无此问题
  • 结构体不用于SAFEARRAY或VARIANT时,不会出现该异常
  • 目标类型库已注册,但通过ProcMon观察到客户端在查找非目标类型库

相关定义

IDL中的结构体定义

typedef [uuid(7C88E088-A91F-4AE0-B7BA-B1594CCFCD7E), version(1.0)] struct ExampleStruct {
    long x;
} ExampleStruct;

COM函数参数定义

HRESULT ComputePi([in] SAFEARRAY(ExampleStruct) param);

问题

请问该异常出现的原因是什么?


异常原因分析

这个问题的核心是**.NET 7的SAFEARRAY封送逻辑处理VT_RECORD类型UDT时,未正确复用已注册的目标类型库,反而尝试导出临时类型库导致路径错误**,具体细节如下:

  1. .NET版本间的封送逻辑差异

    • .NET Framework处理UDT的SAFEARRAY时,直接调用已注册的COM类型库信息完成封送
    • .NET 7的MngdSafeArrayMarshaler在处理VT_RECORD类型时,会尝试将托管结构体导出为临时类型库,但未关联IDL中定义的结构体UUID(7C88E088-A91F-4AE0-B7BA-B1594CCFCD7E)和版本信息
  2. 注册表访问异常的根源
    程序查找非目标类型库,是因为.NET 7导出临时类型库时生成了新的临时GUID,而非使用IDL中指定的结构体标识,导致注册表查询路径错误,触发“类型库未注册”的异常

  3. 触发条件的关联性
    当结构体不用于SAFEARRAY或VARIANT时,.NET 7使用常规结构体封送逻辑,无需导出临时类型库,因此不会触发该异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 17:45:48