C# COM Interop 返回 null 对象导致需要 0x800A01A8 对象

问题描述 投票:0回答:2

我正在编写返回一个对象的 COM 包装器,如果该对象不存在则返回 null。从 VBScript 调用时,返回 null 会引发错误“需要对象:'ComObj.Prop2'”代码 800A01A8...

C#

public class testCOM
{
    public object Func(int i)
    {
        if (i == 1) return new object();
        if (i == 2) return DBNull.Value;
        return null;
    }
}

VBScript

set ComObj = CreateObject("ClassLibrary1.testCOM")

set TestObj = ComObj.Func(1) 'This Works
set TestObj = ComObj.Func(2) 'Throws "Object required: 'ComObj.Func(...)'" Code 800A01A8
set TestObj = ComObj.Func(3) 'Throws "Object required: 'ComObj.Func(...)'" Code 800A01A8
set TestObj = Nothing        'This is what I want to occur with Func(2) and Func(3)

我尝试返回 DBNull.Value,它应该封送为 VT_NULL,但没有运气......

我真的不想用 .HasValue 和 .Value 编写类似于 Nullabe<> 的包装对象...我不喜欢的另一个选择是创建一个 Nothing 对象(没有命名空间内),这样我就可以这样做:

If TestObj Is Nothing And TestObj = "Nothing" Then
    'TestObj was nothing or "Nothing"
End If

如果我使用 Nothing 对象,那么我的 COM 对象必须重新输入 Object 类型,而不是预期的类型化对象,这使得代码有点难以阅读,尽管功能上与我的目的相同。

通过 COM 将空对象返回到 VBScript 的最佳方法是什么?

vbscript null com
2个回答
0
投票

检查界面中的签名并确保其正确。如果我执行以下操作:

public object test(int i) {
    object retval = null;
    if (i == 1) {
        retval = new Object();
    } else if (i == 2) {
        retval = DBNull.Value;
    }
    return retval;
}

接口签名为:

[DispId(1001)]
object test(int i);

然后,在 VBScript 中执行:

' myObject is my instantiated COM class
WScript.Echo TypeName(myObject.test(1))
WScript.Echo TypeName(myObject.test(2))
WScript.Echo TypeName(myObject.test(3))

我回来了:

Object
Null
Empty

0
投票

添加 MarshalAs 有帮助:

[return:MarshalAs(UnmanagedType.IDispatch)]
public object Func(int i)
{
    if (i == 1) return new object();
    if (i == 2) return DBNull.Value;
    return null;
}

但我不确定为什么。 如果您有一个接口,那么该属性应该应用于接口级别。

© www.soinside.com 2019 - 2024. All rights reserved.