gpt4 book ai didi

c# - 为什么这个 C# COM 类可用于 VBScript 而不是 JScript?

转载 作者:数据小太阳 更新时间:2023-10-29 05:20:28 24 4
gpt4 key购买 nike

考虑下面给出的 C# 中与自动化兼容的 COM 库。它遵循一个常见的 COM 模式,即有一个可见的工厂 coclass FooFactory 实现 ICreateFoos,它创建一个 IFoo 类型的对象。 FooFactory 是类型库中唯一的 coclass。 (工厂模式对于 COM 特别有用,因为它不允许参数化构造函数)。

在下面的代码中,我发现我无法从 jscript 访问返回的 IFoo 接口(interface) 除非我使 FooImpl 类 ComVisible(通过取消注释注释行;这使它在类型库中显示为组件类)。 从 VBscript 访问它没有这样的问题

也就是说,我可以运行这个 VBScript:

set ff = CreateObject("jstest.FooFactory")
set foo = ff.CreateFoo(0)
foo.Foo

但是这个功能相同的 JScript 失败了,错误是“C:\temp\jstest\jstest.js(4, 1) Microsoft JScript runtime error: 'foo' is null or not an object ":

var ff = new ActiveXObject("jstest.FooFactory");
var foo = ff.CreateFoo(0)
//WScript.Stdout.WriteLine(null==foo)
foo.Foo();

如果我取消注释该行,我可以看到 null==foo 是 false。

为什么会这样?这是一个错误吗?请注意,我认为这是 JScript 和 C#/.net 特定实现(可能是 IDispatch)的组合的问题,因为我有其他类似的 COM 服务器 - 用 C++ 实现 - 不会从 JScript 中出现这个问题。

如果我取消注释下面代码中的注释行,问题就会消失,使 FooImpl 作为一个组件类可见 - 但我特别不想这样做,因为我不想公开实现细节。一种解决方法似乎是使 FooImpl ComVisible,但将其构造函数标记为内部,这会阻止客户端能够 CoCreate 它,但这并不优雅。

我在带有 Visual Studio 2005、.net 2 的 WinXP SP3 上运行,并且能够在 VirtualBox(均使用 Windows Script Host 5.7)和 Windows 上全新安装 TinyXP 时重现该问题7 Ultimate 使用 .net SDK 2.0、3.0、3.5 和 4.0 (WSH 5.8)。所有操作系统均为 32 位。

库代码:

using System;
using System.Runtime.InteropServices;

[assembly: ComVisible(false)]

namespace jstest
{
[ComVisible(true)]
public interface ICreateFoos
{
IFoo CreateFoo(int importantNumber);
}

[ComVisible(true)]
public interface IFoo
{
void Foo();
}

[ComVisible(true)]
public class FooFactory : ICreateFoos
{
public IFoo CreateFoo(int importantNumber)
{ // in *this* version, we don't use importantNumber yet
return new FooImpl();
}
}

//[ComVisible(true)]
public class FooImpl : IFoo
{
public void Foo()
{
Console.WriteLine("Foo");
}
}
}

您可以编译并注册(您可能必须以管理员身份运行才能重新登录)

csc /target:library jstest.cs
regasm /codebase jstest.dll

最佳答案

当针对从 CreateFoo 为 IDispatch GUID 返回的 IFoo 对象调用 QueryInterface 时,它​​返回 E_NOINTERFACE 除非 ComVisible是为实际实现类设置的。

jscript 准备调用 Foo 方法时,它多次调用 QueryInterface,包括使用这个特定的 GUID,并且由于返回错误,它不会尝试使用调用

vbscript 准备调用 Foo 方法时,它不会检查接口(interface)是否支持 IDispatch。使用 IDispatchEx 的 GUID 调用 QueryInterface 一次,但它似乎只是假设将支持 IDispatch。

关于c# - 为什么这个 C# COM 类可用于 VBScript 而不是 JScript?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3712005/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com