如何在 VBA 中注册类型库

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1651702/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 10:55:52  来源:igfitidea点击:

How to register a type library in VBA

vbatypelib

提问by Joe

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).

我试图从 VBA 代码以编程方式注册一个类型库,使用谷歌发现的技术的两种变体(下面的 Subs RegisterTypeLibrary 和 RegisterTypeLibrary2)。

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.

下面的代码因调用 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

EDIT

编辑

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

我怀疑这与我的类型库有关。我找到了一个解决方案,我已将其作为答案发布在下面。

回答by Joe

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.

我找到了一个解决方案,使用下面的代码。基本上,LoadTypeLibEx(C/C++ 中的 ITypeLib**)的第三个参数被声明为 stdole.IUnknown 而不是 Object。

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

为此,我需要向 VBA 项目添加对 stdole32.tlb 的引用。

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

我怀疑我的类型库存在某些问题,这意味着它不能被声明为 VB(后期绑定)对象。

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

我也可以将第三个参数声明为 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

回答by AMissico

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

我怀疑您的类型库 (TLB) 有错误,因为当我针对第三方 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.

我假设您将使用 VBA 中的 .NET 程序集。因此,我建议您确保可以从 VBA 中引用您的 TLB,而不会出错。

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

请注意,.NET 库公开的所有对象都必须具有不接受任何参数的公共构造函数。这可能是导致问题的原因。