Почему C # null переводится как пустой в VB6, а не Nothing - PullRequest
15 голосов
/ 13 января 2010

У меня есть приложение C #, которое ссылается на VB6 dll. Когда я передаю ноль из C # в функцию dll VB6, ноль переводится как значение Empty (значение) в VB6 вместо Nothing (объект). Например:

 // 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);
 }

Когда я передаю объект (не ноль), он передается в VB6 как объект. Но когда значение null передается в vb6, оно становится типом значения Empty, а не типом объекта Nothing. Кто-нибудь знает почему? и есть ли в любом случае я могу заставить NULL как Nothing в VB6 при передаче из приложения C #?

Большое спасибо.

Ответы [ 6 ]

5 голосов
/ 14 января 2010

Еще немного информации, а не ответ. Я только что запустил эту скретч-программу 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 мог бы быть лучше.

3 голосов
/ 14 января 2010

Так как вы не должны изменять функции в dll VB, как насчет добавления одной?

Public Sub TestFuncEx(ByVal oValue As Variant)
{
   If IsEmpty(oValue) Then
    TestFunc(Nothing)
   Else
    TestFunc(oValue)
   End If
}

Предположительно, это будет работать как 1) это подпрограмма, а не функция, поэтому нет возвращаемого значения и 2) вы передаете по значению, поэтому он не изменяет сам объект.

3 голосов
/ 13 января 2010

Возможно, причина в том, что это ByVal функция. null вероятно маршалируется в вариант типа оценки, который является как можно более "нулевым".

2 голосов
/ 13 января 2010

Вы пробовали:

Public Sub TestFunc(ByVal oValue As Variant)
 {
   ...
   If oValue Is Nothing Then
     Set oValue = someObject
   ElseIf IsEmpty(oValue) Then
     Set oValue = someObject
   End If
   ...

 }

Правка. И я бы согласился с ответом Сандера Рейкена о том, почему вместо null

возвращается Empty
1 голос
/ 17 октября 2011

Я последовал предложению с другого сайта и использовал System.DBNull.Value в вызове метода COM. Это сработало для меня, когда прохождение C # нуль не.

0 голосов
/ 15 января 2010

Поскольку параметр для метода VB6 - это вариант, который вы должны проверять на наличие Nothing, Missing и Empty, поскольку они являются возможными «не значениями или объектами», которые могут передаваться, когда нет действительного значения или объекта.

Отвечая на ваш вопрос, я думаю, это потому, что Variant в VB6 по умолчанию равен Empty, если ваш параметр имеет тип Object Ничего не будет передано, в вашем случае.

Возможно, вы захотите попробовать передать Nothing из VB.Net и посмотреть, что произойдет, если Nothing сохраняется в DLL VB6, вы знаете, что это можно передать, и найдете ответ, посмотрев код IL.

...