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

时间:2012-04-20 15:47:40

标签: com vbscript null nothing

我正在编写返回对象的COM包装器,如果该对象不存在则返回null。从VBScript调用时,返回null会抛出错误“Object required:'ComObj.Prop2'”Code 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,但没有运气......

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

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

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

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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;
}

我不确定为什么。 如果你有一个接口,那么这个属性应该应用在接口级别上。