1

我想使用 tlbinf32.dll 来读取 COM 对象的类型信息。目前我可以访问指向 ITypeLib 接口的指针。我可以使用 VTable 偏移量和 DispCallFunc 手动调用方法和导航,但是我希望使用该库的强大内置功能。

我在想,既然TLI.ClassInfoFromObject(Object As IUnknown)可以用来查询 IDispatch::GetTypeInfo 方法,我可以手动构造一个只实现此方法的虚拟对象,以允许将 TypeInfo 读入内存。类似于手动定义IEnumVariant大多数方法返回的位置E_NOTIMPL = &H80004001。这听起来可行吗?有没有更简单的方法可以使用 VBA 从指针访问 TypeInfo?


更新

需要明确的是,我的问题是我找不到声明 ITypeInfo 接口并允许我直接使用它的方法 - VBAIUnknown从 stole2.tlb 访问,所以我可以很好地使用它,但我唯一能找到 ITypeInfo 声明的地方在 mscorlib.dll 中,但它没有 COMVisible 属性,因此无法在 VBA、AFAIK 和 VBA 中访问它,并且 VBA 没有[ComImport]让您自己使用 GUID 定义它的等效项。所以我想使用 tlbinf32.dll 来避免我不得不使用原始指针。

4

1 回答 1

2

事实证明 tlbinf32.dll 开箱即用,但它是隐藏的。从帮助文件:

ITypeLib As IUnknown
TypeLibInfoFromITypeLib(ByVal ptlib As IUnknown) As TypeLibInfo

每个 TypeLibInfo 内部都是对 ITypeLib 实例的引用。事实上,TypeLibInfo 对象可以看作是 ITypeLib 接口上的一个包装器,它比 ITypeLib 本身更容易编程。要查看两个 TypeLibInfo 对象是否实际引用同一个内部对象,请使用 VB 的 Is 运算符和两个对象的 ITypeLib 属性。对于实际上对应于相同基础类型的 TypeLibInfo 对象,Is 运算符通常会返回 False,但对于内部 ITypeLib 指针则不会。ITypeLib 属性是可设置的,因此您可以将 TypeLibInfo 对象放在现有 ITypeLib 之上。

如果您有 ITypeLib 引用并想要使用 TLI 对象,则可以调用 TLI.TypeLibInfoFromITypeLib 来生成功能齐全的 TypeLibInfo 对象。

ITypeLib 属性和 TypeLibInfoFromITypeLib 方法被视为高级功能并被标记为隐藏。

强调我自己

... ITypeInfo 指针的类似故事

那么如何使用呢?非常简单。首先是从指针中获取 IUnknown 的方法。例如:

Public Function ObjectFromObjPtr(ByVal Address As LongPtr) As IUnknown
    Dim result As IUnknown
    MemLongPtr(VarPtr(result)) = Address
    Set ObjectFromObjPtr = result
    MemLongPtr(VarPtr(result)) = 0
End Function

Private Property Let MemLongPtr(ByVal dest as LongPtr, ByVal value As LongPtr)
    CopyMemory ByVal dest, value, LenB(value)
End Property

随之而来的电话

Dim ITypeLibPtr As LongPtr
ITypeLibPtr = ... 'get the raw pointer

Dim ITypeLibObj As IUnknown
Set ITypeLibObj = ObjectFromObjPtr(ITypeLibPtr)

Dim NiceTypeLib As tli.TypeLibInfo
Set NiceTypeLib = tli.TypeLibInfoFrom(ITypeLibITypeLibObj)

或类似的话

于 2021-01-05T19:37:05.883 回答