如何在VBA中注册类型库

时间:2009-10-30 18:59:06

标签: vba typelib

我正在尝试以编程方式从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

修改

我怀疑这是我的类型库的具体内容。我找到了一个解决方案,我在下面发布了答案。

2 个答案:

答案 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库公开的所有对象都必须具有不接受任何参数的公共构造函数。这可能会导致问题。