Как Вы эффективно копируете BSTR в wchar_t []?

В Java все переменные, которые вы объявляете, на самом деле являются «ссылками» на объекты (или примитивы), а не самими объектами.

При попытке выполнить один метод объекта , ссылка просит живой объект выполнить этот метод. Но если ссылка ссылается на NULL (ничего, нуль, void, nada), то нет способа, которым метод будет выполнен. Тогда runtime сообщит вам об этом, выбросив исключение NullPointerException.

Ваша ссылка «указывает» на нуль, таким образом, «Null -> Pointer».

Объект живет в памяти виртуальной машины пространство и единственный способ доступа к нему - использовать ссылки this. Возьмем этот пример:

public class Some {
    private int id;
    public int getId(){
        return this.id;
    }
    public setId( int newId ) {
        this.id = newId;
    }
}

И в другом месте вашего кода:

Some reference = new Some();    // Point to a new object of type Some()
Some otherReference = null;     // Initiallly this points to NULL

reference.setId( 1 );           // Execute setId method, now private var id is 1

System.out.println( reference.getId() ); // Prints 1 to the console

otherReference = reference      // Now they both point to the only object.

reference = null;               // "reference" now point to null.

// But "otherReference" still point to the "real" object so this print 1 too...
System.out.println( otherReference.getId() );

// Guess what will happen
System.out.println( reference.getId() ); // :S Throws NullPointerException because "reference" is pointing to NULL remember...

Это важно знать - когда больше нет ссылок на объект (в пример выше, когда reference и otherReference оба указывают на null), тогда объект «недоступен». Мы не можем работать с ним, поэтому этот объект готов к сбору мусора, и в какой-то момент VM освободит память, используемую этим объектом, и выделит другую.

5
задан 16 September 2008 в 13:06
поделиться

5 ответов

Объекты BSTR содержат префикс длины, таким образом узнавая, что длина является дешевой. Узнайте длину, выделите новый массив, достаточно большой, чтобы содержать результат, процесс в это, и не забыть освобождать его, когда Вы будете сделаны.

5
ответ дан 18 December 2019 в 07:58
поделиться

Одна вещь иметь в виду является этим BSTR строки, и часто делают, может содержать встроенный, аннулирует. Пустой указатель не означает конец строки.

3
ответ дан 18 December 2019 в 07:58
поделиться

Никогда нет никакой потребности в преобразовании. A BSTR указатель указывает на первый символ строки, и это завершается пустым указателем. Длина хранится перед первым символом в памяти. BSTRs всегда являются Unicode (UTF-16/UCS-2). Было однажды что-то позвонившее 'BSTR ANSI' - существуют некоторые ссылки в API прежней версии - но можно проигнорировать их в текущей разработке.

Это означает, что можно передать a BSTR безопасно к любой функции, ожидающей a wchar_t.

В Visual Studio 2008 можно получить ошибку компилятора, потому что BSTR определяется как указатель на unsigned short, в то время как wchar_t собственный тип. Можно или бросить или выключить wchar_t соответствие /Zc:wchar_t.

4
ответ дан 18 December 2019 в 07:58
поделиться

Во-первых, Вам не, возможно, на самом деле придется сделать ничего вообще, если все, что необходимо сделать, читается содержание. Тип BSTR уже является указателем на завершенный пустым указателем массив wchar_t. На самом деле при проверке заголовков Вы найдете, что BSTR по существу определяется как:

typedef BSTR wchar_t*;

Так, компилятор не может различать их, даже при том, что у них есть другая семантика.

Существует, два важных протеста.

  1. BSTRs, как предполагается, неизменны. Вы никогда не должны изменять содержание BSTR после того, как он был инициализирован. "При изменении его" необходимо создать новый, присваивают новый указатель и выпускают старый (если Вы владеете им).
    [ОБНОВЛЕНИЕ: это не верно;прошу прощения! можно изменить BSTRs на месте; у меня очень редко была потребность.]

  2. BSTRs позволяют содержать встроенные нулевые символы, тогда как традиционные строки C/C++ не.

Если Вы имеете изрядное количество управления источника BSTR и можете гарантировать, что BSTR не имеет встроенным, АННУЛИРУЕТ, можно читать из BSTR, как будто это был wchar_t, и используйте стандартные строковые методы (wcscpy, и т.д.) для доступа к нему. В противном случае Ваша жизнь становится более трудной. Необходимо будет всегда управлять данными или как большим количеством BSTRs, или как динамично выделенный массив wchar_t. Большинство связанных со строкой функций не будет работать правильно.

Давайте предположим, что Вы управляете своими данными или не волнуетесь о ПУСТЫХ УКАЗАТЕЛЯХ. Давайте предположим также, что Вы действительно должны сделать копию и не можете просто считать существующий BSTR непосредственно. В этом случае можно сделать что-то вроде этого:

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

При использовании оберток класса для BSTR обертка должна иметь способ назвать SysStringLen () для Вас. Например:

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

ОБНОВЛЕНИЕ: Это - хорошая статья о предмете кем-то намного более хорошо осведомленным, чем я:
"Eric [Lippert] полное руководство по семантике BSTR"

ОБНОВЛЕНИЕ: Замененный strcpy () с wcscpy () в примере

8
ответ дан 18 December 2019 в 07:58
поделиться

Используйте ATL и CStringT затем, можно просто использовать оператор присваивания. Или можно использовать макросы USES_CONVERSION, они используют выделение "кучи", таким образом, Вы будете уверены, что не пропустите память.

0
ответ дан 18 December 2019 в 07:58
поделиться
Другие вопросы по тегам:

Похожие вопросы: