ОК, так как мы подтвердили, что параметры поступают как объекты (COM), а не как строки, последняя загадка, которую нужно решить, - это почему вы получаете ошибку 13, несоответствие типов.
Я быисследовать эту проблему с двух сторон: во-первых, используйте TypeName (), чтобы получить объект, который VB6 считает своим (например, TypeName (e.Person)).Затем подумайте, действительно ли у VB6 есть средства для доступа к членам этого объекта - для начала лучше всего обратиться к Обозревателю объектов в IDE VB6.Если класс объекта обнаруживается в этом, но не предоставляет никаких членов (даже с включенным Show Hidden Members), то этот класс, вероятно, не отображается должным образом как COM-объект.
==== Предыдущий ====
Для хихиканья, когда вы остановитесь или остановитесь в Sub IEventHandler_OnEvent (), зайдите в окно Immediate VB6 IDE и посмотрите, допустимы ли они:
?sender.ToString
?e.ToString
Кроме того, отказаться от использования ByRef и перейти с ByVal;если вы действительно не пытаетесь изменить значение ссылки в зависимости от состояния экземпляра, вам не нужен ByRef.
Я подозреваю, что вы действительно получаете объекты;видимая строка, которую вы видите, является результатом члена ToString (), который каким-то образом сделан как свойство COM по умолчанию.
Один из способов проверить вышеупомянутое подозрение - попробовать их в окне Immediate VE6 IDE (когда выполнение остановлено в IEventHandler_OnEvent ()):
?typename(sender)
?typename(e)
Typename должно показывать String, еслилюбой из них действительно является строкой.
==== Предыдущий ====
Джефф, пожалуйста, дайте мне знать, если эти проекты VB6 и .NET являются верным примером вашей проблемы.
В .NET я создал проект DLL, имеющий один интерфейс и один класс, оба с экспозицией COM:
==== .NET, файл IComFun.vb
Imports System.Runtime.InteropServices
<GuidAttribute("b3f1ab4f-dc99-4990-ade1-8a4833d8bcab"), _
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)> _
Public Interface IComFun
Sub OnFoo(ByVal sender As Object, ByVal e As Object)
End Interface
==== .NET, файл ComFun.vb
<ComClass(ComFun.ClassId, ComFun.InterfaceId, ComFun.EventsId)> _
Public Class ComFun
#Region "COM GUIDs"
' These GUIDs provide the COM identity for this class
' and its COM interfaces. If you change them, existing
' clients will no longer be able to access the class.
Public Const ClassId As String = "257a4ed2-1f27-4d8e-bcf2-f90828ae649b"
Public Const InterfaceId As String = "4431a515-3c01-4fff-b281-20ec8ad0c0b6"
Public Const EventsId As String = "9b44258f-142e-4dd0-bc22-6d24d1f58657"
#End Region
' A creatable COM class must have a Public Sub New()
' with no parameters, otherwise, the class will not be
' registered in the COM registry and cannot be created
' via CreateObject.
Public Sub New()
MyBase.New()
End Sub
Public Sub Ping(ByVal sender As Object, ByVal e As Object)
DirectCast(sender, IComFun).OnFoo(sender, e)
End Sub
End Class
В VB6 я создал стандартный проект EXE со ссылками на COM-библиотеку на основе .NET через файл TLB, имеющий одинформа (содержащая одну кнопку) и один класс, например:
==== VB6, файл Form1.frm
Dim x As Class1
Dim y As Class1
Dim z As ComFun.ComFun
Private Sub cmdPing_Click()
If x Is Nothing Then
Set x = New Class1
End If
If y Is Nothing Then
Set y = New Class1
End If
If z Is Nothing Then
Set z = New ComFun.ComFun
End If
z.Ping x, y
End Sub
==== VB6, файл Class1.cls
Implements ComFun.IComFun
Private Sub IComFun_OnFoo(ByVal sender As Variant, ByVal e As Variant)
Stop
End Sub
Я сделал вышеупомянутые проекты и скомпилировал их, а затем запустил VB6 EXE (в IDE) и нажал кнопку.Когда я добрался до оператора Stop в IComFun_OnFoo, я получал реальные объекты, а не строки - другими словами, он работал так, как вам нужно, чтобы он работал.Я также посмотрел на стек вызовов (в VB6 IDE), чтобы убедиться, что вызывается неосновной код.
Итак, я действительно не решил вашу проблему, но надеюсь лучше понять ситуацию.