vba - VBA COM 库中的这些 _B_var_Xxxxx 和 _B_str_Xxxxx 成员究竟是什么?

标签 vba parsing com

想象一下下面的函数调用:

foo = UCase("bar")

我正在解析这段代码,并确定 UCase 是一个函数调用;现在我想将该函数调用解析为它在其中定义的 COM 库中的函数声明。

这个想法是实现一个代码检查,确定当 String 返回函数存在时何时使用 Variant 内置函数,就像这里的 UCase可以改用 $

似乎我所追求的函数在 COM 库中被声明为 _B_var_Ucase_B_str_UCase;我在 VBA.Strings 模块中获取一个 UCase 成员,但它返回 VT_VOID - 换句话说,它是一个 过程,不是函数

我可以硬编码一些特定于该组函数的逻辑,这样当我的解析器代码遇到 UCase 时,我可以连接 _B_var_(对于 UCase $,我可以将 _B_str_) 连接到我要解析的标识符,如果幸运的话,我会得到我的解析器代码以正确地将引用分配给正确的构建-在函数声明中。

但这纯粹是猜测。

知道 _var_代表Variant_str_代表String,但我缺少的部分恰恰是如何将这些隐藏函数与我正在解析的 VBA 代码中的 UCase 函数调用相关联。

UCase("bar") 是对 VBA.Strings.UCase 过程 的调用吗?那么它作为一个函数是如何工作的呢?如果不是,那么 VBA 如何知道将 UCase 标记解释为对 _B_var_UCase 的调用?是否有我可以依赖的一致命名方案,或者 UCase_B_var_UCase 之间是否存在我没​​有看到的关系? B 到底有什么用?

网络对 VBA 标准库的内部结构非常沉默,我希望这里的某人可能对此有所了解。

最佳答案

看看 TYPEATTR 结构,特别是 typekindtdescAlias 成员。

typedef struct tagTYPEATTR {
  GUID     guid;
  LCID     lcid;
  DWORD    dwReserved;
  MEMBERID memidConstructor;
  MEMBERID memidDestructor;
  LPOLESTR lpstrSchema;
  ULONG    cbSizeInstance;
  TYPEKIND typekind;
  WORD     cFuncs;
  WORD     cVars;
  WORD     cImplTypes;
  WORD     cbSizeVft;
  WORD     cbAlignment;
  WORD     wTypeFlags;
  WORD     wMajorVerNum;
  WORD     wMinorVerNum;
  TYPEDESC tdescAlias;
  IDLDESC  idldescType;
} TYPEATTR, *LPTYPEATTR;

tdescAlias

If typekind is TKIND_ALIAS, specifies the type for which this type is an alias.

所以,UCase(String)_B_var_Ucase(String)别名 (其中参数和返回值都是隐式 Variant。

并且,UCase$(String As String) As String_B_str_UCase(String As String) As String别名

您可以直接从VB/VBA 中调用这些底层函数,但必须使用方括号,因为_B_str_UCase_B_var_UCase不是 VB/VBA 中的有效标识符。

Dim s As String
Dim v As Variant

s = [_B_str_UCase]("abc")
v = [_B_var_UCase](Null)

's = "ABC"
'v = Null

Wayback Machine 的 cache 缓和了 Web 令人发指的沉默肖恩·巴克斯特 (Sean Baxter) 的一系列内容丰富且有趣的文章,但也保留了格式,here .

The TKIND_ALIAS type kind indicates description of a typedef. The name of the typedef is the name of the type (acquired through GetDocumentation), and the alias type is TYPEATTR::tdescAlias.

至于B_B_str_UCase_B_var_UCase很难说得很准确,但值得记住的是,在 COM 中,字符串实际上是 BSTR

A BSTR (Basic string or binary string) is a string data type that is used by COM, Automation, and Interop functions

此 MSDN article进一步说明:

COM code uses the BSTR to store a Unicode string, short for “Basic String”. (So called because this method of storing strings was developed for OLE Automation, which was at the time motivated by the development of the Visual Basic language engine.)

然后继续说:

If you write a function which takes an argument of type BSTR then you are required to accept NULL as a valid BSTR and treat it the same as a pointer to a zero-length BSTR. COM uses this convention, as do both Visual Basic and VBScript, so if you want to play well with others you have to obey this convention. If a string variable in VB happens to be an empty string then VB might pass it as NULL or as a zero-length buffer — it is entirely dependent on the internal workings of the VB program.

所以可能 B是提醒那些函数的作者,返回类型应该 是一个BSTR,或者B 可能只是表示base 函数。我怀疑它对原始开发人员以外的任何人都很重要。

编辑

OleView 提供了这些细节:

module Strings{ 
    [entry(527), helpcontext(0x000f6eab)]
    BSTR _stdcall _B_str_UCase([in] BSTR String);

    [entry(528), helpcontext(0x000f659b)]
    VARIANT _stdcall _B_var_UCase([in] VARIANT* String);
}

interface _HiddenInterface {
    [restricted, helpcontext(0x000f659b)]
    void _stdcall UCase();
}

条目(527 和 528)可以在 DLL 导出中找到:

ordinal hint RVA      name
    ...
    527   C8 0005E8A0 rtcUpperCaseBstr
    528   C9 00070418 rtcUpperCaseVar
    ....

关于vba - VBA COM 库中的这些 _B_var_Xxxxx 和 _B_str_Xxxxx 成员究竟是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36002870/

相关文章:

vba - VBS InStr 的问题 - 使用嵌套的 InStr 作为可选的开始参数

vba - Excel VBA : How to create an autofilter with an exception to the filter?

java - 如何从java中的String中删除特定的String

regex - 如何将段落拆分为由句点 (.) 分隔的句子,除非句点是缩写的一部分?

vba - 选择文本并将其删除的代码

Excel 360 VBA 更改数据透视表过滤器

java - 如何格式化日期/时间字符串? ( java )

powershell - 无法在PowerShell函数中运行[System .__ ComObject] .InvokeMember

c# - 强制 .NET 类型实例化为 COM

python - comtypes 中的 COM 对象 VARIANT 参数(python)