【问题标题】:How to convert BSTR to String with C如何使用 C 将 BSTR 转换为字符串
【发布时间】:2021-01-31 07:14:36
【问题描述】:

我正在用 C 语言开发一个函数来提取 UI 元素的类名。该函数返回 BSTR,我想使用 Py_BuildValue 将此值传递给 python。

BSTR element_class;

hr = IUIAutomationElement_get_CurrentClassName(element,element_class);
if(SUCCEEDED(hr)){
  arglist = Py_BuildValue("(z)", element_class);
}

if(element_class != NULL)
      free(element_class); ????

编译后我收到以下警告:

'function': 'BSTR *' differs in levels of indirection from 'BSTR'

我想了解此警告以及如何正确执行此操作。另外,我想释放这个 element_class 的内存,但我也不知道该怎么做。非常感谢您的帮助。

编辑 1: 我实现了删除警告,只需在 element_class 中添加 $。但是,当我使用 Py_BuildValue 时,我只得到第一个字母,而不是类的全名。

【问题讨论】:

  • 那么 SysFreeString() 是用于释放 BSTR 的函数。但是,IDK Python 期望什么样的字符串。 BSTR 是一个 Unicode 字符串。取决于 Python 期望使用的字节长度和编码。要转换为多字节字符串(Windows 有时称为“Ansi”),如果要转换为 char* 类型的字符串,请使用 WideCharToMultiByte()。
  • 添加$?那不可能是标准 C。而且 BSTR 是 UTF-16 编码的,所以一旦你得到它就必须解码它。
  • @JosephWillcoxson 感谢您的帮助。使用我当前的代码,我得到了类名的第一个字母,这意味着如果类名是“hello”,我只会得到“h”。如果我理解你,我必须创建一个新变量 WCHAR 并使用函数 WideCharToMultiByte()。如果是这样,请告诉我如何使用该功能,我正在查看 Microsoft 的文档,但我不明白。对不起,如果问题是愚蠢的。 docs.microsoft.com/en-us/windows/win32/api/stringapiset/…
  • 不确定您正在使用的实现,但它看起来就像IUIAutomation...()调用需要一个指向BSTR对象的指针 ,所以试试:hr = IUIAutomationElement_get_CurrentClassName(element, &element_class);ref
  • 看起来@MarkRansom 给出了正确答案。您只得到“h”的原因是因为您使用的参数“z”需要一个以空字符结尾的字符串:“hello\0”。 BSTR 的格式类似于“h\0e\0l\0l\0o\0\0”。 IOW,在字节串中,每个字符之间都是空值,所以函数只是将“h”视为字符串的整体。

标签: python c com ui-automation


【解决方案1】:

将 cmets 中包含的所有提示放在一起,我认为这就是您应该使用的。

BSTR element_class;

hr = IUIAutomationElement_get_CurrentClassName(element, &element_class);
if(SUCCEEDED(hr)){
  arglist = Py_BuildValue("(u)", element_class);
}

if(element_class != NULL)
      SysFreeString(element_class);

【讨论】:

  • 感谢您帮助巩固提示。但是,当我使用 SysFreeString 时出现以下错误:错误 LNK2001:未解析的外部符号 __imp_SysFreeString。你知道为什么吗?
  • @sergioMoreno 检查SysFreeString 的文档。它说它是库OleAut32.lib 的一部分,如果您包含正确的标题,它应该会自动链接。
  • 我在 windows.h 之后包含了 oleauto.h。但是,我仍然遇到同样的错误。我在以下标头#define COBJMACROS 和#define _WIN32_WINNT 0x400 之前使用。你知道我做错了什么吗?提前感谢您的帮助。
  • @sergioMoreno 定义 WIN32... 必须是第一位的。除此之外我什么都想不出来。也许是时候搜索网络或提出新问题了。
猜你喜欢
  • 1970-01-01
  • 2015-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 2014-01-19
相关资源
最近更新 更多