Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#COM互操作返回空对象导致需要0x800A01A8对象_Com_Vbscript_Null_Nothing - Fatal编程技术网

C#COM互操作返回空对象导致需要0x800A01A8对象

C#COM互操作返回空对象导致需要0x800A01A8对象,com,vbscript,null,nothing,Com,Vbscript,Null,Nothing,我正在编写返回对象的COM包装器,如果对象不存在,则返回null。从VBScript调用时,返回null将抛出错误“需要对象:'comboj.Prop2'”代码800A01A8 C# VBScript set ComObj = CreateObject("ClassLibrary1.testCOM") set TestObj = ComObj.Func(1) 'This Works set TestObj = ComObj.Func(2) 'Throws "Object required: '

我正在编写返回对象的COM包装器,如果对象不存在,则返回null。从VBScript调用时,返回null将抛出错误“需要对象:'comboj.Prop2'”代码800A01A8

C#

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对象(在no namespace中),以便我可以执行以下操作:

If TestObj Is Nothing And TestObj = "Nothing" Then
    'TestObj was nothing or "Nothing"
End If
如果我使用Nothing对象,那么我的COM对象必须是reutrn类型的对象,而不是预期的类型化对象,这使得代码更难阅读,尽管功能与我的目的相同


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

检查界面中的签名并确保其正确无误。如果我这样做:

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

检查界面中的签名并确保其正确无误。如果我这样做:

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

添加MarshalAs有助于:

[return:MarshalAs(UnmanagedType.IDispatch)]
public object Func(int i)
{
    if (i == 1) return new object();
    if (i == 2) return DBNull.Value;
    return null;
}
我不知道为什么。
如果您有一个接口,则此属性应应用于接口级别。

添加MarshalAs有助于:

[return:MarshalAs(UnmanagedType.IDispatch)]
public object Func(int i)
{
    if (i == 1) return new object();
    if (i == 2) return DBNull.Value;
    return null;
}
我不知道为什么。
如果您有一个接口,那么这个属性应该应用于接口级别。

我很感谢您的响应。不幸的是,您的建议没有将返回的对象/值分配给变量。相反,它直接将其传递给另一个函数TypeName。如果您的vbscript为:如果您的vbscript尝试设置TestObj=myObject.test(2)以便
回显TypeName(TestObj)
,则代码800A01A8将出错。显然,
set
需要设置一个对象,所以我不能返回null,它不是一个对象。如果你不使用“设置”,它就会工作。我已经求助于在根命名空间中创建一个Nothing类,并测试
如果TypeName(TestObj)=“Nothing”,那么
您就不能在尝试设置它之前使用IsNull进行测试吗?正如您可能从我跟踪这个线程中猜到的那样,我已经接受了返回一个global::Nothing对象的实例。但是,为了响应使用IsNull,我假设您的意思是
如果不是IsNull(ComObj.Func(2)),那么设置TestObj=ComObj.Func(2)
。不幸的是,这将执行函数两次,工作量加倍。然而,你确实给了我一个想法。如果TypeName(obj)=“Empty”,我可以创建
函数包装器(obj),然后设置包装器=无其他设置包装器=obj End If End Function
。现在,这应该可以了:
Set TestObj=Wrapper(CommObj.Func(2))
。谢谢你的帮助!我感谢你的答复。不幸的是,您的建议没有将返回的对象/值分配给变量。相反,它直接将其传递给另一个函数TypeName。如果您的vbscript为:如果您的vbscript尝试设置TestObj=myObject.test(2)以便
回显TypeName(TestObj)
,则代码800A01A8将出错。显然,
set
需要设置一个对象,所以我不能返回null,它不是一个对象。如果你不使用“设置”,它就会工作。我已经求助于在根命名空间中创建一个Nothing类,并测试
如果TypeName(TestObj)=“Nothing”,那么
您就不能在尝试设置它之前使用IsNull进行测试吗?正如您可能从我跟踪这个线程中猜到的那样,我已经接受了返回一个global::Nothing对象的实例。但是,为了响应使用IsNull,我假设您的意思是
如果不是IsNull(ComObj.Func(2)),那么设置TestObj=ComObj.Func(2)
。不幸的是,这将执行函数两次,工作量加倍。然而,你确实给了我一个想法。如果TypeName(obj)=“Empty”,我可以创建
函数包装器(obj),然后设置包装器=无其他设置包装器=obj End If End Function
。现在,这应该可以了:
Set TestObj=Wrapper(CommObj.Func(2))
。谢谢你的帮助!