Тип варианта VB6 для типа .NET - PullRequest
4 голосов
/ 13 июля 2010

У меня есть некоторый код VB6, который не может быть легко изменен и выглядит следующим образом:

Dim cCount as Long
Dim rCount as Long
Dim result()

Set mx = CreateObject("Component.Class")
Dim rtn = mx.GetList(rCount,cCount,result)

Метод, который он вызывает, в настоящее время является компонентом VB6, который мы перенесли в .NET с одной проблемой. Мы не уверены, какой тип ищет результат (), так как это вариантный тип. Мы пробовали объект, объект [], объект [] [], строку, строку [] и т. Д., Ни один из которых не сработал.

Вот пример:

public bool GetList(ref long rCount, ref long cCount, ref object result)
{
  ...
}

Я даже пытался установить третий параметр в VariantWrapper, так как он добавит ByRef по мере необходимости:

public bool GetList(ref long rCount, ref long cCount, VariantWrapper result)
{
  ...
}

Любые идеи, как я могу установить входящий результат, чтобы у меня не было необработанного исключения?

Я создал тестовый интерфейс (для COM), тестовый класс и тестовое приложение VB6, чтобы убедиться, что это проблема с Variant. Итак, это определено так:

.NET интерфейс:

[DispId(1)]
[ComVisible(true)]
string Test(ref object[] value);

VB 6 метод:

Private Sub Command1_Click()
    Set mx = CreateObject("Component.Class")
    Dim result()
    MsgBox mx.Test(result)
End Sub

Та же проблема, что и описанная выше. В VB6 меня просто выгоняет. Если я компилирую и запускаю его, я получаю общее исключение .NET, и оно выбрасывает меня.

Ответы [ 4 ]

4 голосов
/ 14 июля 2010

Ваша декларация C # неверна.VB6 "Long" является 32-битным по историческим причинам.Это int на стороне C #.При неправильном кадре стека у вас нет шансов получить правильно переданный аргумент «result».

Это должен быть SafeArray of Variants, object [] в C #.

1 голос
/ 13 июля 2010

Я думаю, что ключевое слово ref может вызывать некоторые проблемы здесь. Типы должны точно соответствовать, чтобы это работало.

Однако, если ваш метод просто принимает ссылку на любое object по значению (вместо ref), он может получить что угодно, поскольку все происходит от object in. NET.

Насколько хорошо это соответствует взаимодействию VB6 / COM, я не знаю. Но, похоже, это хотя бы стоит того:

C # код :

public string GetTypeName(object value)
{
    return value.GetType().FullName;
}

Код VB6 :

Set mx = CreateObject("Component.Class")
Dim result()

MsgBox mx.GetTypeName(result)

Это вам что-нибудь дает?


Вот идея. Я мог бы ошибаться здесь - у меня нет большого опыта в переносе приложений VB6 в .NET - но мне кажется, что если вы сможете добраться до (эквивалент C #) этой строки ...

Set mx = CreateObject("Component.Class")

... тогда ты золотой. Вы можете использовать отражение, чтобы выяснить, какие параметры хочет метод GetList.

Сначала получите объект System.Type, представляющий тип mx:

Type mxType = mx.GetType();

Затем найдите метод GetList для этого типа:

MethodInfo[] getListMethods = mxType.GetMember("GetList")
    .OfType<MethodInfo>()
    .Where(m => m.GetParameters().Length == 3)
    .ToArray();

Это даст вам массив MethodInfo[] всех открытых перегрузок GetList, принимающий 3 параметра. Отсюда возможные типы result будут:

Type[] possibleResultTypes = getListMethods
    .Select(m => m.GetParameters()[2].ParameterType)
    .ToArray();
1 голос
/ 13 июля 2010

Установить точку останова на линии mx.GetList(rCount,cCount,result). После того, как вы нажмете, добавьте выражение «быстрый просмотр» mx.GetList(rCount,cCount,result). Окно инструментов должно показать вам, какой будет конечный тип времени выполнения. Скорее всего, это «comresult» и не даст много информации, но может дать подсказку для типа возвращаемого значения.

0 голосов
/ 05 июля 2012

Я знаю только, как это используется в .Net, где вы передаете ссылку на Variant, например:

 int port = 2;
 object pvPort = new System.Runtime.InteropServices.VariantWrapper(port);
 gimp.SetPort(ref pvPort);

После этого установите точку останова и проверьте тип варианта, если вы не уверены в этом.

Главное использовать VariantWrapper, чтобы dll понимал.

...