【问题标题】:How to convert char * to BSTR?如何将 char * 转换为 BSTR?
【发布时间】:2010-10-11 00:03:10
【问题描述】:

如何将 char * 从 C dll 传递到 VB

这里是示例代码:

void Cfunc(char *buffer,int len)
{
  BSTR buf_bstr = SysAllocString((BSTR)buffer);
  VBptr.VBfunc(buf_bstr,len);
}

这个功能不起作用,实际上一些其他值被发送到VB而不是实际值。

有人可以提出解决方案吗?

【问题讨论】:

  • 你能举一个原始字符串与发送的错误值的例子吗?
  • 您的(原始)问题似乎是字符宽度。 BSTR 始终是宽字符(COM 都是 Unicode)。强制转换不会自动加宽字符,而是将字节解释为 wchar_t*。
  • 此伪代码存在内存泄漏。您调用 SysAllocString(),但在不再需要字符串后不要释放它。
  • 对于它的价值,一个非常好的经验法则是,如果你必须强制转换某些东西才能使其工作 - 就像在这里你将 char* 缓冲区强制转换为 BSTR 的情况一样 - 那么你'可能做错了,应该寻找其他转换。演员表的合法使用往往相当少见,因此对演员表持怀疑态度是个好主意。

标签: c string com vb6 bstr


【解决方案1】:

使用_bstr_t:

_bstr_t bstrt(buffer);

这里是holy grail of string conversion articles

【讨论】:

  • _bstr_t 是一个类。我想对纯 C 没有用处。
【解决方案2】:

我对 ajryan 的回答没有任何异议,但这里有一个替代方案……

SysAllocString 被定义为采用 OLECHAR * 类型的参数。你给它一个 char *.这些不是一回事。在某些情况下,它们可能是相同的,但你不能依赖它。所以首先你需要将你的 char * 转换成 OLECHAR *。有一个名为 A2OLE 的宏可以为您执行此操作,并且在 char * 和 OLECHAR * 相同的情况下,宏编译为空(我认为)。

有关 A2OLE 及其朋友的详细信息,请参阅this page

哦,将您的 char * 转换为 BSTR 实际上根本不会改变它,它既不是 BSTR 也不是 OLECHAR *。

【讨论】:

  • 顺便说一句,如果没有使用 SysAllocString() 系列函数之一分配字符串,则将 WCHAR* 转换为 BSTR 也是一个坏主意。如果您传递此类伪 BSTR 的调用在其上调用 SysStringLen(),这样做可能会导致崩溃。
【解决方案3】:

拨打MultiByteToWideChar(),然后拨打SysAllocString()SysAllocStringLen()

当您不再需要 BSTR 时,不要忘记致电 SysFreeString()

详细说明(SysAllocStringLen() 变体——它更短更快):

  1. 调用 MultiByteToWideChar() 并传递 0 作为第五和第六个参数。它将返回与 ANSI 字符串等效的 Unicode 字符数。请记住,ANSI 字符串可以包含任何字符,而不仅仅是 ASCII,因此在给定 ANSI 字符串长度的情况下手动计算 Unicode 字符数的任何尝试可能在某些情况下有效,而在其他情况下无效。

  2. 使用SysAllocStringLen() 为 BSTR 分配缓冲区。传递 0 作为第一个参数,Unicode 字符的数量作为第二个参数。您现在有一个正确分配但未初始化的 BSTR。它已经有尾随零的位置,并且该尾随零已正确放置。

  3. 第二次调用MultiByteToWideChar(),这次通过分配的BSTR。该函数会将字符串转换为 Unicode 并将结果复制到 BSTR。现在您有了一个正确分配的 BSTR,其中包含您的 ANSI 字符串的 Unicode 等价物。

  4. 将 BSTR 传递到 VB。享受吧。

  5. 调用SysFreeString()释放BSTR。

【讨论】:

  • 我的代码仍然无法正常工作,我已经这样修改了。 void Cfunc(char *buffer,int len) { BSTR buf_bstr; ULONG c字符; if (0 == MultiByteToWideChar(0, 0, buffer, cCharacters, buf_bstr, cCharacters)); VBptr.VBfunc(buf_bstr,len); } VB Exe 崩溃了。
  • 嗨 Sharptooth.. 我是这个 COM 的新手 :(
【解决方案4】:

这是我使用sharptooths答案编写的代码

    int wslen = MultiByteToWideChar(CP_ACP, 0, str, strlen(str), 0, 0);
    BSTR bstr = SysAllocStringLen(0, wslen);
    MultiByteToWideChar(CP_ACP, 0, str, strlen(str), bstr, wslen);
    // Use bstr here
    SysFreeString(bstr);

请注意,使用 -1 作为字符串长度会导致结果中包含空终止符

【讨论】:

    【解决方案5】:

    试试 _tchar* 数组,而不是 char* 数组。因为 Sysallocstring 在 32 位应用程序中只接受 Unicode 字符。

    【讨论】:

      猜你喜欢
      • 2011-04-08
      • 1970-01-01
      • 2013-01-04
      • 2011-05-17
      • 1970-01-01
      • 1970-01-01
      • 2011-08-09
      • 2016-02-14
      • 2015-09-27
      相关资源
      最近更新 更多