你如何有效地复制BSTR到wchar_t []? [英] How do you efficiently copy BSTR to wchar_t[]?

查看:161
本文介绍了你如何有效地复制BSTR到wchar_t []?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个BSTR对象,我想转换为复制到一个wchar__t对象。棘手的事情是BSTR对象的长度可以是从几千字节到几百千字节的任何地方。有没有一种有效的方式来复制数据?我知道我可以只声明一个wchar_t数组,并始终分配最大可能的数据,它需要持有。然而,这意味着为可能只需要几千字节的东西分配几百千字节的数据。任何建议?

解决方案

首先,你可能不需要做任何事情,如果你需要做的是阅读内容。 BSTR类型是一个指向空终止的wchar_t数组的指针。事实上,如果你检查头,你会发现BSTR基本上定义为:

  typedef BSTR wchar_t *; 

因此,编译器不能区分它们,即使它们有不同的语义。 >

有两个重要的警告。


  1. 是不可变的。在初始化之后,不应更改BSTR的内容。如果您更改,您必须创建一个新的指针分配新的指针并释放旧指针(如果您拥有它)。

    [ :这不是真的;抱歉!您可以修改BSTRs到位; ]


  2. BSTR允许包含嵌入的空字符,而传统的C / C ++字符串不允许。 / p>


如果您对BSTR的来源有相当大的控制权,并且可以保证BSTR没有嵌入式NULL,你可以从BSTR读取,就像它是一个wchar_t,并使用常规字符串方法(wcscpy等)来访问它。如果没有,你的生活变得更难。你必须总是将你的数据操作为更多的BSTR,或者作为一个动态分配的wchar_t数组。大多数字符串相关的函数将无法正常工作。



让我们假设你控制你的数据,或者不用担心NULL。让我们假设你真的需要做一个副本,不能只是直接读取现有的BSTR。在这种情况下,你可以这样做:

  UINT length = SysStringLen(myBstr); //向COM询问BSTR的大小
wchar_t * myString = new wchar_t [lenght + 1]; //注意:SysStringLen不
//包含NULL所需的空间

wcscpy(myString,myBstr); //或你最喜欢的更安全的字符串函数

// ...

delete myString; // Done

如果您正在为BSTR使用类封装器,则封装器应该有一个方法调用SysStringLen()为你。例如:

  CComBString use .Length(); 
_bstr_t use .length();

UPDATE :这是一篇很好的文章比我更了解:

Eric [Lippert]的完成指导BSTR语义
更新:在示例中替换了strcpy()与wcscpy()


I have a BSTR object that I would like to convert to copy to a wchar__t object. The tricky thing is the length of the BSTR object could be anywhere from a few kilobytes to a few hundred kilobytes. Is there an efficient way of copying the data across? I know I could just declare a wchar_t array and alway allocate the maximum possible data it would ever need to hold. However, this would mean allocating hundreds of kilobytes of data for something that potentially might only require a few kilobytes. Any suggestions?

解决方案

First, you might not actually have to do anything at all, if all you need to do is read the contents. A BSTR type is a pointer to a null-terminated wchar_t array already. In fact, if you check the headers, you will find that BSTR is essentially defined as:

typedef BSTR wchar_t*;

So, the compiler can't distinguish between them, even though they have different semantics.

There is are two important caveat.

  1. BSTRs are supposed to be immutable. You should never change the contents of a BSTR after it has been initialized. If you "change it", you have to create a new one assign the new pointer and release the old one (if you own it).
    [UPDATE: this is not true; sorry! You can modify BSTRs in place; I very rarely have had the need.]

  2. BSTRs are allowed to contain embedded null characters, whereas traditional C/C++ strings are not.

If you have a fair amount of control of the source of the BSTR, and can guarantee that the BSTR does not have embedded NULLs, you can read from the BSTR as if it was a wchar_t and use conventional string methods (wcscpy, etc) to access it. If not, your life gets harder. You will have to always manipulate your data as either more BSTRs, or as a dynamically-allocated array of wchar_t. Most string-related functions will not work correctly.

Let's assume you control your data, or don't worry about NULLs. Let's assume also that you really need to make a copy and can't just read the existing BSTR directly. In that case, you can do something like this:

UINT length = SysStringLen(myBstr);        // Ask COM for the size of the BSTR
wchar_t *myString = new wchar_t[lenght+1]; // Note: SysStringLen doesn't 
                                           // include the space needed for the NULL

wcscpy(myString, myBstr);                  // Or your favorite safer string function

// ...

delete myString; // Done

If you are using class wrappers for your BSTR, the wrapper should have a way to call SysStringLen() for you. For example:

CComBString    use .Length();
_bstr_t        use .length();

UPDATE: This is a good article on the subject by someone far more knowledgeable than me:
"Eric [Lippert]'s Complete Guide To BSTR Semantics" UPDATE: Replaced strcpy() with wcscpy() in example

这篇关于你如何有效地复制BSTR到wchar_t []?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆