У меня проблема при попытке передать массив обратно в вызывающую COM.
По сути, у меня есть общий список классов, который я хочу вернуть вызывающему COM, вы не можете использовать обобщенные значения в COM, поэтому он должен быть строго типизирован. Я полагал, что просто возврат .ToArray () в Список даст мне то, что мне нужно.
Когда я использую его в VB6, он отлично работает. В отладчике. Когда я компилирую приложение и запускаю его как простой исполняемый файл, он падает с нарушением доступа к памяти. Я довольно озадачен. Я не могу перехватить какие-либо ошибки в VB или в компоненте .NET, поэтому я предполагаю, что что-то происходит в трансляции COM.
Сбой при "return a" в getList ()
Журнал событий приложений содержит эту ошибку:
Сбой приложения project1.exe, версия 1.0.0.0, штамп 49fb60d8, сбой модуля msvbvm60.dll, версия 6.0.98.2, штамп 4802a186, отладка? 0, адрес ошибки 0x00106154.
Вот код VB6 для справки, это глупо просто.
Private Sub Form_Load()
Dim c1 As IClass1
Dim c2
Set c1 = New Class1
For Each c2 In c1.getList
Debug.Print c2.Value
Next
End Sub
И код .NET:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace TestCOM
{
public interface IClass1
{
List<IClass2> MyList { get; }
IClass2[] getList();
}
public class Class1 : IClass1
{
public List<IClass2> MyList { get; private set; }
public Class1()
{
this.MyList = new List<IClass2>();
this.MyList.Add(new Class2());
this.MyList.Add(new Class2());
}
public IClass2[] getList()
{
try
{
System.IO.File.WriteAllText(@"C:\COMLog1.txt", "Hi.");
IClass2[] a = new IClass2[this.MyList.Count];
System.IO.File.WriteAllText(@"C:\COMLog1.txt", "Bye.");
for (int i = 0; i < this.MyList.Count; i++)
{
a[i] = this.MyList[i];
}
System.IO.File.WriteAllText(@"C:\COMLog1.txt", "Sup.");
//The logging appears on disk all the way to here, so the failure appears to be in the interop layer.
return a;
}
catch (Exception e)
{
System.IO.File.WriteAllText(@"C:\COMLog.txt", string.Format("Error:\n{0}", e.Message));
}
return null;
}
}
public interface IClass2
{
int Value { get; }
}
public class Class2: IClass2
{
public int Value { get; private set; }
public Class2()
{
Random r = new Random();
this.Value = r.Next();
}
}
}
Проблема связана с поздним связыванием со стороны VB. Использование раннего связанного массива решает проблему, вот окончательный код VB для тестового приложения:
Private Sub Form_Load()
Dim c1 As IClass1
Dim c2() As IClass2
Dim x
Set c1 = New Class1
c2 = c1.getList
For Each x In c2
Debug.Print x.Value
Next
End Sub