我正在尝试以编程方式从VBA代码注册一个类型库,使用两种使用Google找到的技术变体(下面的Subs RegisterTypeLibrary和RegisterTypeLibrary2)。
以下代码在对LoadTypeLib / LoadTypeLibEx的调用上发生访问冲突时崩溃。我究竟做错了什么?如果它是相关的,则类型库是使用tlbexp从.NET程序集生成的TLB文件。
Private Enum RegKind
RegKind_Default = 0
RegKind_Register = 1
RegKind_None = 2
End Enum
Private Declare Function LoadTypeLibEx Lib "oleaut32.dll" ( _
pFileName As Byte, ByVal RegKind As RegKind, pptlib As Object) As Long
Private Declare Function LoadTypeLib Lib "oleaut32.dll" ( _
pFileName As Byte, pptlib As Object) As Long
Private Declare Function RegisterTypeLib Lib "oleaut32.dll" ( _
ByVal ptlib As Object, szFullPath As Byte, _
szHelpFile As Byte) As Long
Private Sub RegisterTypeLibrary(FileName As String)
Dim abNullTerminatedFileName() As Byte
Dim objTypeLib As Object
Dim lHResult As Long
abNullTerminatedFileName = FileName & vbNullChar
lHResult = LoadTypeLib(abNullTerminatedFileName(0), objTypeLib)
If lHResult <> 0 Then
Err.Raise lHResult, "LoadTypeLib", "Error registering type library " & FileName
End If
lHResult = RegisterTypeLib(objTypeLib, abNullTerminatedFileName(0), 0)
If lHResult <> 0 Then
Err.Raise lHResult, "RegisterTypeLib", "Error registering type library " & FileName
End If
Exit Sub
End Sub
Private Sub RegisterTypeLibrary2(FileName As String)
Dim abNullTerminatedFileName() As Byte
Dim objTypeLib As Object
Dim lHResult As Long
abNullTerminatedFileName = FileName & vbNullChar
lHResult = LoadTypeLibEx(abNullTerminatedFileName(0), ByVal RegKind_Register, objTypeLib)
If lHResult <> 0 Then
Err.Raise lHResult, "LoadTypeLibEx", "Error registering type library " & FileName
End If
End Sub
修改
我怀疑这是我的类型库的具体内容。我找到了一个解决方案,我在下面发布了答案。
答案 0 :(得分:2)
我找到了一个解决方案,使用下面的代码。基本上,LoadTypeLibEx的第三个参数(C / C ++中的ITypeLib **)被声明为stdole.IUnknown而不是Object。
为此,我需要将对stdole32.tlb的引用添加到VBA项目中。
我怀疑我的类型库有一些东西意味着它不能被声明为VB(后期绑定)对象。
我也可以将第三个参数声明为Long,但我不确定它是否会导致引用计数问题。
Private Enum RegKind
RegKind_Default = 0
RegKind_Register = 1
RegKind_None = 2
End Enum
Private Declare Function LoadTypeLibEx Lib "oleaut32.dll" ( _
pFileName As Byte, ByVal RegKind As RegKind, pptlib As stdole.IUnknown) As Long
Public Sub RegisterTypeLibrary(FileName As String)
Dim abNullTerminatedFileName() As Byte
Dim objTypeLib As stdole.IUnknown
Dim lHResult As Long
abNullTerminatedFileName = FileName & vbNullChar
lHResult = LoadTypeLibEx(abNullTerminatedFileName(0), ByVal RegKind_Register, objTypeLib)
If lHResult <> 0 Then
Err.Raise lHResult, "LoadTypeLibEx", "Error registering type library " & FileName
End If
End Sub
答案 1 :(得分:1)
我怀疑你的类型库(TLB)有错误,因为我提供的代码在我针对第三方TLB进行测试时有效。
我假设您要从VBA使用.NET程序集。因此,我建议您确保可以无错误地从VBA引用您的TLB。
请注意,.NET库公开的所有对象都必须具有不接受任何参数的公共构造函数。这可能会导致问题。