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

.NET 8 ComVisible对象通过CreateObject()创建时出现‘Object required’错误

VB6后期绑定调用.NET 8 COM对象时“Object required”错误的解决

问题场景

用.NET 8和C#创建了一个COM可见的计数器类,代码如下:

SimpleCounter.cs

using System.Runtime.InteropServices;

namespace Counters
{
    [ComVisible(true)]
    [Guid("01FB5599-3CD1-462E-98AA-C29614C0AFEC")]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("Counters.SimpleCounter")]
    public class SimpleCounter : ISimpleCounter
    {
        private int _counter;

        public SimpleCounter()
        {
            _counter = 0;
        }

        public int Counter
        {
            get { return _counter; }
            set { _counter = value; }
        }

        public void IncrementCounter()
        {
            _counter++;
        }
    }
}

ISimpleCounter.cs(初始版本)

using System.Runtime.InteropServices;

namespace Counters
{
    [ComVisible(true)]
    [Guid("D65B22DD-4E59-4C11-88B3-67A2535D472E")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface ISimpleCounter
    {
        public int Counter { get; set; }

        public void IncrementCounter();
    }
}

Counters.csproj

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>net8.0-windows</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <PlatformTarget>x86</PlatformTarget>
        <EnableComHosting>true</EnableComHosting>
        <Platforms>AnyCPU;x86</Platforms>
    </PropertyGroup>

</Project>

项目构建后生成Counters.dll和Counters.comhost.dll,通过dscom32生成并注册TLB,再用regsvr32注册comhost.dll,操作符合.NET 8 COM规范。

在VB6中测试时,早期绑定(直接声明类型)可以正常运行:

Private Sub Command1_Click()

    Dim obj As New Counters.SimpleCounter
    MsgBox "Counter is " & obj.Counter
    obj.IncrementCounter
    MsgBox "Counter now is " & obj.Counter

End Sub

但使用后期绑定(CreateObject)创建对象时,即使obj不为Nothing,调用obj.Counter仍会触发“Object required”错误:

' 报错的代码示例
Private Sub Command1_Click()

    Dim obj As Object
    Set obj = CreateObject("Counters.SimpleCounter")
    MsgBox "Counter is " & obj.Counter ' 此处触发错误

End Sub

原因分析

VB6的后期绑定依赖IDispatch接口来动态解析对象的属性和方法。当接口标记为InterfaceType(ComInterfaceType.InterfaceIsIUnknown)时,.NET仅向COM暴露IUnknown接口,不提供IDispatch支持,导致后期绑定无法识别Counter属性和IncrementCounter方法,从而抛出错误。

而InterfaceType(ComInterfaceType.InterfaceIsDual)会让接口同时暴露IUnknown和IDispatch,既支持早期绑定,也兼容VB6的后期绑定机制。

解决方法

将接口的InterfaceType属性修改为ComInterfaceType.InterfaceIsDual即可解决问题:

修改后的ISimpleCounter.cs

using System.Runtime.InteropServices;

namespace Counters
{
    [ComVisible(true)]
    [Guid("D65B22DD-4E59-4C11-88B3-67A2535D472E")]
    [InterfaceType(ComInterfaceType.InterfaceIsDual)]
    public interface ISimpleCounter
    {
        public int Counter { get; set; }

        public void IncrementCounter();
    }
}

重新构建并注册COM对象后,使用CreateObject的后期绑定代码即可正常运行。


内容的提问来源于stack exchange,提问作者Étienne Laneville

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 12:55:54