Ich habe ein Problem beim Versuch, ein Array an einen COM-Aufrufer zurückzugeben.Verwendung von NET Generic List ToArray in einem COM Called Wrapper verursacht Zugriffsverletzung, fehlt mir etwas?
Grundsätzlich habe ich eine generische Liste von Klassen, die ich an den COM-Aufrufer zurückgeben möchte, können Sie nicht Generics in COM verwenden, so dass es stark typisiert werden muss. Ich dachte, ich würde einfach ein. ToArray() auf der Liste zurückgeben, würde mir geben, was ich brauche.
Wenn ich es in VB6 verwende, funktioniert es perfekt. Im Debugger. Wenn ich die App kompiliere und sie als reine ausführbare Datei ausführe, stürzt sie mit einer Speicherzugriffsverletzung ab. Ich bin ziemlich ratlos. Ich kann keine Fehler in VB oder in der .NET-Komponente abfangen, daher vermute ich, dass etwas in der COM-Übersetzung verloren geht.
Es schlägt fehl, auf "return a" in getList()
Anwendungsereignisprotokoll enthält diesen Fehler:
Fehlgeschlagene Anwendung project1.exe, Version 1.0.0.0, Stempel 49fb60d8, Modul msvbvm60.dll Verwerfungen, Version 6.0.98.2, Stempel 4802a186, debuggen? 0, Fehleradresse 0x00106154.
Hier ist der VB6-Code als Referenz, es ist dumm einfach.
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
Und der .NET-Code:
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();
}
}
}
Das Problem aus der späten Bindung auf der VB Seite stammt. Mit einem frühen gebundenen Array löst das Problem, hier ist der letzte VB-Code für die Testanwendung:
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
* Wo * nicht abstürzen oder? Haben Sie einige Debugging-Ausgaben eingegeben, um den genauen Standort und die Zustände der Objekte für den Absturz zumindest zu lokalisieren? –
Es stürzt bei getList ab, ich habe versucht, es zu versuchen/zu fangen und den gefangenen Fehler in einer Datei zu protokollieren. Der Fehler scheint nicht von .NET gefangen werden. – Boarder2
Gibt es FatalExecutionErrors im Ereignisprotokoll? –