Почему С# null переводится как пустой в VB6, а не в Nothing
У меня есть приложение С#, которое ссылается на dll VB6. Когда я передаю null из С# в функцию dll VB6, значение null преобразуется как значение Empty (value) в VB6 вместо 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. Кто-нибудь знает почему? и есть ли в любом случае я могу заставить null как ничего в VB6 при передаче из приложения С#?
Большое спасибо.
Ответы
Ответ 1
Дополнительная информация, а не ответ. Я просто запускал эту программу 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 и указывает вариант, содержащий ссылку на объект.
9
9
vnt Is Nothing
Я не тестировал перенос TestStub в другой компонент, но я думаю, что он все равно будет работать. Поэтому я думаю, что .NET-маршаллинг для COM может сделать лучше.
Ответ 2
Вероятно, причина в том, что это функция ByVal
. null
, вероятно, маршалируется в valueetype Variant, который как можно более "null".
Ответ 3
Поскольку вы не должны изменять функции в dll VB, как насчет добавления одного?
Public Sub TestFuncEx(ByVal oValue As Variant)
{
If IsEmpty(oValue) Then
TestFunc(Nothing)
Else
TestFunc(oValue)
End If
}
Предположительно, это будет работать как 1) он не является функцией, поэтому нет никакого возвращаемого значения и 2) вы проходите по значению, чтобы он не изменял сам объект.
Ответ 4
Вы пробовали:
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 Rijken ответит, почему Empty
возвращается вместо null
Ответ 5
Я выполнил предложение с другого сайта и использовал System.DBNull.Value в вызове метода COM. Это сработало для меня, когда пропустить С# null не удалось.
Ответ 6
Поскольку параметр для метода VB6 является вариантом, вы должны тестировать Nothing, Missing и Empty, потому что они являются возможными "не значением или объектом", которые могут быть переданы, когда нет реального значения или объекта.
В ответ на ваш вопрос, я думаю, это связано с тем, что вариант VB6 по умолчанию имеет значение Empty, если ваш параметр имеет тип Object. Ничего не будет передано в вашем случае.
Вы можете попробовать передать Nothing из VB.Net и посмотреть, что произойдет, если Nothing не сохранится к VB6 DLL, тогда вы знаете, что можно передать его и найти ответ, посмотрев код IL.