【发布时间】:2021-12-27 18:56:00
【问题描述】:
我用VB.NET在VS2017中做了一个DLL:
Imports System.Runtime.InteropServices
<ComClass(ComClass1.ClassId, ComClass1.InterfaceId, ComClass1.EventsId)>
Public Class ComClass1
#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 = "c67bcd70-54d0-4498-97be-a5f954790dec"
Public Const InterfaceId As String = "7ef1a8ce-bcc1-464e-8dc3-fc164bdb7ea3"
Public Const EventsId As String = "9939eabd-1102-4e34-9735-54664e3536bd"
#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 Xposition As Int32
Public GoX As Int32
Public Function MoveX() As Int32
Dim target As Int32
target = Convert.ToInt32(Rnd() * 1000)
Xposition = target
Return Xposition
End Function
Public Function ReadX() As Int32
Dim target As Int32
target = Convert.ToInt32(Rnd() * 1000 - GoX)
Xposition = target
Return Xposition
End Function
End Class
我在开发 Widows 10 PC 上以管理员身份编译了 DLL。 我将 DLL 文件复制到运行 VB6 的 Windows XP 目标机器并得到运行时错误 453。
VB6 代码:
Private Declare Function GSCloseServer Lib "GSWDLL32.DLL" () As Long
Private Declare Function MoveX Lib "C:\Temp\VB_Applications\My_DLL_Test\MyNewDLL.dll" () As Integer
Private Sub btnMove_Click()
Call test
End Sub
Private Sub btnStop_Click()
Dim Running As Integer
' Unload MyGraph
Set Form1 = Nothing
Running = GSCloseServer()
If Running = 0 Then
MsgBox "Close Server OK: " & Running, vbOKOnly
Else
MsgBox "Close Server Error " & Running, vbOKOnly
End If
Unload Me
End Sub
Private Sub test()
'txtbxReadBack.Text = ComClass1.Xposition
txtbxReadBack.Text = MoveX
End Sub
我以管理员身份运行 VS2017,因此 DLL 似乎已在开发 PC 上正确注册。
【问题讨论】:
-
你不需要那个构造函数。我知道文档说它是必需的,但是在 .Net 中,如果您没有为某个类型声明任何构造函数,它将为您生成无参数构造函数。
-
您在 VB.NET 中构建一个 COM 对象,因此您必须像 VB6 中的 COM 对象一样调用它,而不是像带导出的标准 dll 一样。
-
如何在VB6中将其称为com对象? 在vb6项目中,从Project-References中选择MyNewDLL接口。然后您可以定义和实例化 COM 对象,例如
Dim oMyDLL = New namespace.ComClass1和txtbxReadBack.Text = oMyDLL.MoveX,删除函数声明。在测试机器上,您的程序集需要注册(regasm.exe)。可能是在开发机器上编译程序集执行了程序集的注册。 -
快速说明(现在与您的问题无关),您已将 MoveX 声明为 .Net 端的 Int32 和 VB6 端的 Integer。 VB6 整数是 2 个字节,但 .Net Int32 是 4 个字节。您应该使用 VB6 Long 代替,它也是 4 个字节。
-
tlb 是通过注册 dll 创建的,包含 COM 接口定义。在 vb6 Project-References 中引用 tlb。 dll 的注册还添加了指向 tlb 和 dll 的注册表项(以及它们的路径);不要在不重新注册的情况下移动 dll。构建 dll 时,(在 VS2019 中)My Project-Compile 下有一个“Register for COM interop”复选框;选中该选项后,VS 在构建期间将注册 dll。但如果你没有引用那台电脑上的 dll(例如来自 vb6),你实际上不需要在那里注册它。
标签: vb.net dll com vb6 interop