Перед тем как перейти к ответу, важно отметить, что в вашем запросе упоминается использование интерфейсов в DLL на Delphi, которые должны быть доступны в VB.NET приложении. Вы хотите передать коллекцию этих интерфейсов для возможности перебора элементов в цикле for each в VB.NET.
Подтвержденное решение
Вы нашли решение, которое работает, но выразили недовольство им. Вы создали класс TIWindows, который наследует интерфейсы IWindows, IEnumerable и IEnumVariant. В VB.NET вы определили интерфейс IWindows, наследующий IEnumerable и переопределили метод GetEnumerator.
<ComImport(), Guid("D9174D5A-4946-4E5A-95B1-2CD521C3BF73"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
Public Interface IWindows
Inherits IEnumerable
Shadows Function GetEnumerator() As IEnumerator
End Interface
В VB.NET, при вызове кода, вы создаете объект IWindows, и затем используете цикл для перебора элементов:
Dim Windows As IWindows
Dim Window As IWindow
Try
Windows = Session.TopLevelWindows
For Each Window In Windows
TextBox1.Text = TextBox1.Text & Window.Caption
Next
Catch ex As Exception
' Обработка исключения
End Try
Вы упомянули, что при использовании обобщенного типа IEnumerator(Of IDNKWindow) возникает ошибка из-за невозможности маршалинга обобщенных типов.
Альтернативный ответ: использование safe array
В качестве альтернативы, можно рассмотреть возврат safe array интерфейсов IUnknown из Delphi. Это упростит использование на стороне VB.NET, где массив можно будет перебрать в цикле for each как обычный массив объектов.
Преимущества использования safe array:
Упрощение использования на стороне VB.NET.
Возможность перебора элементов с помощью цикла for each.
Не требуется реализация интерфейсов IEnumerable и IEnumerator в Delphi.
Как это работает:
В Delphi, создайте метод, который возвращает safe array интерфейсов IUnknown.
В VB.NET, используйте этот safe array как обычный массив объектов, перебирая элементы в цикле for each.
Пример кода для Delphi
function GetWindows: array of IUnknown;
var
Windows: TArray<IWindow>;
begin
SetLength(Windows, CountOfWindows);
// Заполнение массива объектами интерфейсов IWindow
Result := Windows as array of IUnknown;
end;
Пример кода для VB.NET
Dim windowsArray As Array Of IWindow
Try
windowsArray = GetWindows() ' Предполагается, что функция GetWindows существует
For Each window In windowsArray
' Работа с каждым интерфейсом IWindow
Next
Catch ex As Exception
' Обработка исключения
End Try
Использование safe array может упростить реализацию и сделать код более удобным для использования в VB.NET. Тем не менее, вам потребуется тщательно протестировать это решение, чтобы убедиться в его работоспособности и отсутствии побочных эффектов.
Пользователь столкнулся с необходимостью передачи коллекции интерфейсов из DLL на Delphi для использования в приложении на VB.NET с возможностью перебора элементов в цикле `for each`.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS