Question

I am trying to register a type library programatically from VBA code, using two variants of a technique found using Google (Subs RegisterTypeLibrary and RegisterTypeLibrary2 below).

The code below crashes with an access violation on the call to LoadTypeLib / LoadTypeLibEx. What am I doing wrong? In case it's relevant, the type library is a TLB file generated from a .NET assembly using tlbexp.

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

EDIT

I suspect it is something specific about my type library. I've found a solution which I've posted as an answer below.

Was it helpful?

Solution

I've found a solution, using the code below. Basically, the third parameter to LoadTypeLibEx (ITypeLib** in C/C++) is declared as stdole.IUnknown instead of as Object.

To do so, I needed to add a reference to stdole32.tlb to the VBA project.

I suspect there is something about my type library that means it can't be declared as a VB (late-bound) Object.

I could also have declared the third parameter as Long, but I'm not sure that wouldn't lead to problems with reference counting.

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

OTHER TIPS

I suspect your type library (TLB) has errors because the code you provided works when I tested against a third-party TLB.

I am assuming you are going to use your .NET Assembly from VBA. Therefore, I suggest you make sure you can reference your TLB from VBA without errors.

Note, that all objects exposed by your .NET library must have public constructors that accept no arguments. This may be causing the problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top