我有一个引用VB6 dll的C#应用程序。当我将C#中的null传递给VB6 dll函数时,null在VB6中被转换为值Empty(value),而不是Nothing(object)。例如:
// function in vb6 dll that referenced by c# app
Public Sub TestFunc(ByVal oValue As Variant)
{
...
if oValue is Nothing then
set oValue = someObject
end if
...
}
// main c# code
private void Form1_Load(object sender, EventArgs e)
{
object testObject = new object();
testObject = null;
TestFunc(testObject);
}
当我传递一个对象(非null)时,它将作为对象传递给VB6。但是当null传递给vb6时,它变为值类型为Empty,而不是对象类型Nothing。谁知道为什么?无论如何,当从c#app传递时,我可以强制null为VB6中的Nothing吗?
非常感谢。
答案 0 :(得分:5)
更多信息,而不是答案。我刚刚运行了这个VB6临时程序来确认Nothing
是否可以通过ByVal
。有可能。
Private Sub Form_Load()
Call TestSub(Nothing)
End Sub
Private Sub TestSub(ByVal vnt As Variant)
Debug.Print VarType(Nothing)
Debug.Print VarType(vnt)
If vnt Is Nothing Then Debug.Print "vnt Is Nothing"
If IsEmpty(vnt) Then Debug.Print "vnt Is Empty"
End Sub
我得到了以下输出。请注意,9是vbObject,表示持有Object引用的Variant。
9
9
vnt Is Nothing
我还没有测试过移动TestStub到另一个组件,但我认为它仍然有用。所以我认为.NET的COM编组可以做得更好。
答案 1 :(得分:3)
原因可能是它是ByVal
函数。 null
可能被编组为一个尽可能为'null'的值类型Variant。
答案 2 :(得分:3)
既然你不应该修改VB dll中的函数,那么添加一个呢?
Public Sub TestFuncEx(ByVal oValue As Variant)
{
If IsEmpty(oValue) Then
TestFunc(Nothing)
Else
TestFunc(oValue)
End If
}
据推测,这可能会起作用1)它是一个子函数而不是一个函数,因此没有返回值,2)你正在传递值,所以它不会修改对象本身。
答案 3 :(得分:2)
你试过了吗?
Public Sub TestFunc(ByVal oValue As Variant)
{
...
If oValue Is Nothing Then
Set oValue = someObject
ElseIf IsEmpty(oValue) Then
Set oValue = someObject
End If
...
}
编辑 - 我同意Sander Rijkens的回答,为什么Empty
被归还而不是null
答案 4 :(得分:1)
我遵循了另一个网站的建议,并在COM方法调用中使用了System.DBNull.Value。这对我来说很有用,因为传递C#null没有。
答案 5 :(得分:0)
由于VB6方法的参数是Variant,您应该测试Nothing,Missing和Empty,因为它们是可能在没有实际值或对象可用时传递的“非值或对象”。
在回答您的问题时,我认为这是因为VB6中的Variant默认为Empty,如果您的参数类型为Object,则在您的情况下将传入Nothing。
您可能想尝试从VB.Net传递Nothing,看看会发生什么,如果Nothing持续存在于VB6 DLL,那么您知道可以传入它并通过查看IL代码找到答案。< / p>