431 / 385 / 200
Регистрация: 12.08.2011
Сообщений: 1,610

Создание массива BSTR

26.07.2013, 13:46. Показов 3479. Ответов 18
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Как преобразовать нижеследующий код, чтобы строки не выводились, а создавался массив? Количество BSTR заранее неизвестно, но их будет не более 10. Таким образом, можно создать массив размерностью 11, а в качестве признака, что строк больше нет, использовать NULL. Но если есть способ лучше или проще, то я буду только рад.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
int listVMs(IVirtualBox *virtualBox)
{
    HRESULT rc;
 
    /*
     * First we have to get a list of all registered VMs
     */
    SAFEARRAY *machinesArray = NULL;
 
    rc = virtualBox->get_Machines(&machinesArray);
    if (SUCCEEDED(rc))
    {
        IMachine **machines;
        rc = SafeArrayAccessData (machinesArray, (void **) &machines);
        if (SUCCEEDED(rc))
        {
            for (ULONG i = 0; i < machinesArray->rgsabound[0].cElements; ++i)
            {
                BSTR str;
 
                rc = machines[i]->get_Name(&str);
                if (SUCCEEDED(rc))
                {
                    printf("Name: %S\n", str);
                    SysFreeString(str);
                }
            }
 
            SafeArrayUnaccessData (machinesArray);
        }
 
        SafeArrayDestroy (machinesArray);
    }
 
    return 0;
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
26.07.2013, 13:46
Ответы с готовыми решениями:

Работа с BSTR
Помогите пожалуйста разобраться с BSTR. Как строку char преобразовать в BSTR вручную? Допустим есть переменная типа BSTR. В нее надо...

BSTR to String
Привет всем, подскажите плиз как BSTR *value перевести в строку, никак не могу найти решение

BSTR to .txt file
Приветствую. Исходная задача получить html source с TWebBrowser Получить его удалость только в формате BSTR Собственно вот как...

18
Модератор
 Аватар для vxg
3404 / 2175 / 353
Регистрация: 13.01.2012
Сообщений: 8,436
26.07.2013, 16:10
C++
1
2
3
4
5
6
7
8
9
            BSTR *a = new BSTR[machinesArray->rgsabound[0].cElements];
            for (ULONG i = 0; i < machinesArray->rgsabound[0].cElements; ++i)
            {
                rc = machines[i]->get_Name(&a[i]);
                if (FAILED(rc))
                {
                    a[i] = 0;
                }
            }
1
431 / 385 / 200
Регистрация: 12.08.2011
Сообщений: 1,610
26.07.2013, 16:24  [ТС]
Спасибо! А если ещё упростить задачу? Допустим, заранее известны все возможные имена машин. Вот так правильно?
C++
1
2
3
4
5
6
BSTR[5] MachinesList = {
L"Windows 2000",
L"Windows XP",
L"Windows Vista",
L"Windows 7",
NULL}
0
Модератор
 Аватар для vxg
3404 / 2175 / 353
Регистрация: 13.01.2012
Сообщений: 8,436
26.07.2013, 18:02
Цитата Сообщение от Vtulhu Посмотреть сообщение
Вот так правильно?
думаю нет.
1 - зачем в конце ноль если итак все ясно? разве что у вас по задаче требуется куда-то потом этот список передавать без указания размера
2 - вместо L"" надо вроде SysAllocString(L"") ну и потом естественно когда уже не нужно - освобождать
0
431 / 385 / 200
Регистрация: 12.08.2011
Сообщений: 1,610
26.07.2013, 21:00  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
думаю нет.
1 - зачем в конце ноль если итак все ясно?
Почему-то казалось, что так удобнее. Я уже организовывал похожие массивы в ситуации, когда их может понадобиться дополнять (между запусками программы), а отслеживать количество (прописывать константу) лень.

2 - вместо L"" надо вроде SysAllocString(L"") ну и потом естественно когда уже не нужно - освобождать
А вот так? Кстати, в других источниках встречал, что надо делать OLESTR("Windows 2000"), или это эквивалентно?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const MachinesCount = 4;
BSTR[MachinesCount] MachinesList;
MachinesList[0] = SysAllocString(L"Windows 2000");
MachinesList[1] = SysAllocString(L"Windows XP");
MachinesList[2] = SysAllocString(L"Windows Vista");
MachinesList[3] = SysAllocString(L"Windows 7");
 
IMachine machine = NULL;
HRESULT rc;
for (int i=0; i<MachinesCount; i++) {
  rc = VirtualBox->FindMachine(MachinesList[i], &machine);
  if (SUCCEEDED(rc)) break;
}
 
if (machine) exploreMachine(machine);
 
for (int i=0; i<MachinesCount; i++) {
  MachinesList[i] = SysFreeString();
}
0
Модератор
 Аватар для vxg
3404 / 2175 / 353
Регистрация: 13.01.2012
Сообщений: 8,436
27.07.2013, 06:48
Цитата Сообщение от Vtulhu Посмотреть сообщение
встречал, что надо делать OLESTR("Windows 2000"), или это эквивалентно?
понятия не имею. есть WinAPI функция SysAllocString и она делает то что нужно
Цитата Сообщение от Vtulhu Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const MachinesCount = 4; //оо?
BSTR[MachinesCount] MachinesList; //эээ??
MachinesList[0] = SysAllocString(L"Windows 2000");
MachinesList[1] = SysAllocString(L"Windows XP");
MachinesList[2] = SysAllocString(L"Windows Vista");
MachinesList[3] = SysAllocString(L"Windows 7");
IMachine machine = NULL;
HRESULT rc;
for (int i=0; i<MachinesCount; i++) {
* rc = VirtualBox->FindMachine(MachinesList[i], &machine);
* if (SUCCEEDED(rc)) break;
}
if (machine) exploreMachine(machine);
for (int i=0; i<MachinesCount; i++) {
* MachinesList[i] = SysFreeString(); //уууу!
}
что ЭТО???
0
431 / 385 / 200
Регистрация: 12.08.2011
Сообщений: 1,610
27.07.2013, 10:53  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
понятия не имею. есть WinAPI функция SysAllocString и она делает то что нужно
Подразумевалось SysAllocString(OLESTR("Windows"))

что ЭТО???
Людей, общающихся междометиями, мне и в реале хватает.
0
Модератор
 Аватар для vxg
3404 / 2175 / 353
Регистрация: 13.01.2012
Сообщений: 8,436
27.07.2013, 10:59
Цитата Сообщение от Vtulhu Посмотреть сообщение
Подразумевалось SysAllocString(OLESTR("Windows"))
тогда наверное да. точно сказать не могу - привык к L""
Цитата Сообщение от Vtulhu Посмотреть сообщение
Людей, общающихся междометиями, мне и в реале хватает.
код который вы привели очень странный. может он из будущего? в том смысле что C++ судя по обсуждениям новых стандартов дрейфует в сторону VBA - типы не нужно указывать при объявлении и т.п. - прямо как у вас в коде (там где нет ничего после const) + смутила форма записи в которой [] стоят после типа, а не после имени + вот это
C++
1
* MachinesList[i] = SysFreeString();
вообще не пойму как может работать
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
27.07.2013, 12:09
Цитата Сообщение от Vtulhu Посмотреть сообщение
А вот так? Кстати, в других источниках встречал, что надо делать OLESTR("Windows 2000"), или это эквивалентно?
Это не только не эквивалентно, но еще источник распостраненной ошибки.
Хотя тип BSTR в заголовках SDK объявлен как указатель на WCHAR, это не одно и то же.
BSTR-строка хранит информацию о длине, в отличие от обычного указателя на C-строку.
Поэтому BSTR можно передавать через границы процессов (с помощью COM-маршаллинга).
Короче, если работаете с COM-строками, используйте только SysAllocString/SysFreeString.
0
431 / 385 / 200
Регистрация: 12.08.2011
Сообщений: 1,610
27.07.2013, 12:18  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
код который вы привели очень странный. может он из будущего?
Всё гораздо проще - это опечатки. Программирование - не основное моё занятие, а С++ - не основной мой язык.
0
Модератор
 Аватар для vxg
3404 / 2175 / 353
Регистрация: 13.01.2012
Сообщений: 8,436
27.07.2013, 16:55
Цитата Сообщение от Убежденный Посмотреть сообщение
Это не только не эквивалентно, но еще источник распостраненной ошибки.
Хотя тип BSTR в заголовках SDK объявлен как указатель на WCHAR, это не одно и то же.
BSTR-строка хранит информацию о длине, в отличие от обычного указателя на C-строку.
Поэтому BSTR можно передавать через границы процессов (с помощью COM-маршаллинга).
Короче, если работаете с COM-строками, используйте только SysAllocString/SysFreeString.
непонятно как это относится к OLESTR()
C++
1
#define OLESTR(str) L##str
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
27.07.2013, 18:05
Если работаем с COM (особенно касается outproc-серверов), нельзя использовать OLESTR вместо SysAllocString.
0
Модератор
 Аватар для vxg
3404 / 2175 / 353
Регистрация: 13.01.2012
Сообщений: 8,436
27.07.2013, 18:58
Цитата Сообщение от Убежденный Посмотреть сообщение
Если работаем с COM (особенно касается outproc-серверов), нельзя использовать OLESTR вместо SysAllocString.
просто человек спрашивал про эквивалентность макросов L и OLESTR. результат работы макроса он по-честному передавал в SysAllocString
0
431 / 385 / 200
Регистрация: 12.08.2011
Сообщений: 1,610
29.07.2013, 07:36  [ТС]
В качестве fast&dirty solution сделал вот так (просто чтобы проверить, что всё остальное работает):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
IMachine* getMachine(IVirtualBox* box, int index) {
    IMachine *machine = NULL;
    BSTR name;
    switch (index) {
        case 1: name = SysAllocString(L"Windows 2000"); break;
        case 2: name = SysAllocString(L"Windows XP"); break;
        case 3: name = SysAllocString(L"Windows Vista"); break;
        case 4: name = SysAllocString(L"Windows 7"); break;
        default: return NULL;
    }
    HRESULT rc = box->FindMachine(name, &machine);
    SysFreeString(name);
    if FAILED(rc) return NULL;
 
    return machine;
}
Неправильно, неэффективно, но зато понятно даже мне. Конечно, хотелось бы как-то покрасивее сделать.
0
Модератор
 Аватар для vxg
3404 / 2175 / 353
Регистрация: 13.01.2012
Сообщений: 8,436
29.07.2013, 11:30
Цитата Сообщение от Vtulhu Посмотреть сообщение
Неправильно, неэффективно
ваш вариант не сильно хуже вот такого
C++
1
2
3
4
5
6
7
8
9
10
11
    BSTR name[4] =
    {
        SysAllocString(L"Windows 2000"),
        SysAllocString(L"Windows XP"),
        SysAllocString(L"Windows Vista"),
        SysAllocString(L"Windows 7")
    };
    HRESULT rc = box->FindMachine(index >= 1 && index <= 4? name[index - 1] : 0, &machine);
    int n = sizeof(name) / sizeof(name[0]);
    for (int i = 0; i < n; i++)
        SysFreeString(name[i]);
2
431 / 385 / 200
Регистрация: 12.08.2011
Сообщений: 1,610
29.07.2013, 12:15  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
ваш вариант не сильно хуже вот такого
Спасибо, именно так я хотел, но не мог переделать! Такой способ лучше уже хотя бы потому, что выделение и очищение памяти происходит один раз. А в моём варианте при каждом вызове функции создаётся новый BSTR.
0
Модератор
 Аватар для vxg
3404 / 2175 / 353
Регистрация: 13.01.2012
Сообщений: 8,436
29.07.2013, 15:51
Цитата Сообщение от Vtulhu Посмотреть сообщение
в моём варианте при каждом вызове функции создаётся новый BSTR
вообще то и в моем тоже

Добавлено через 26 секунд
...разве что вынести name за пределы функции
0
431 / 385 / 200
Регистрация: 12.08.2011
Сообщений: 1,610
29.07.2013, 16:03  [ТС]
Цитата Сообщение от vxg Посмотреть сообщение
вообще то и в моем тоже

Добавлено через 26 секунд
...разве что вынести name за пределы функции
Я был уверен, что Вы это и подразумевали...

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// when attach DLL
BSTR name[4] =
    {
        SysAllocString(L"Windows 2000"),
        SysAllocString(L"Windows XP"),
        SysAllocString(L"Windows Vista"),
        SysAllocString(L"Windows 7")
    };
 
// inside function
    HRESULT rc = box->FindMachine(index >= 1 && index <= 4? name[index - 1] : 0, &machine);
 
// when detach DLL
    int n = sizeof(name) / sizeof(name[0]);
    for (int i = 0; i < n; i++)
        SysFreeString(name[i]);
1
Модератор
 Аватар для vxg
3404 / 2175 / 353
Регистрация: 13.01.2012
Сообщений: 8,436
29.07.2013, 16:33
Цитата Сообщение от Vtulhu Посмотреть сообщение
это
тогда - да
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
29.07.2013, 16:33
Помогаю со студенческими работами здесь

Преобразовать String в BSTR
Доброго времени суток. Подскажите как преобразовать:String в BSTR. Заранее благодарен.

function(String^ bstr)
Здравствуйте. В своей программе я использовал элемент ActiveX (.ocx). С помощью которого, нарисовал в форме объект для воспроизведения...

Как преобразовать BSTR в String?
Собственно, вопрос в теме: Как преобразовать BSTR в String? Добавлено через 16 минут Создается COM объект...вызывается его метод -...

BSTR* указатель на массив значений
В ATL-проекте есть метод: interface ISW_COM : IDispatch{ ........ HRESULT GetCustomInfoList( BSTR* pVal); он должен вызвать метод...

Как перевести строку в BSTR*
Как перевести обычную строку в BSTR* ???


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
Опции темы

Новые блоги и статьи
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
PowerShell Snippets
iNNOKENTIY21 11.11.2025
Модуль PowerShell 5. 1+ : Snippets. psm1 У меня модуль расположен в пользовательской папке модулей, по умолчанию: \Documents\WindowsPowerShell\Modules\Snippets\ А в самом низу файла-профиля. . .
PowerShell и онлайн сервисы. Валюта (floatrates.com руб.)
iNNOKENTIY21 11.11.2025
PowerShell функция floatrates-rub Примеры вызова: # Указанная валюта 'EUR' floatrates-rub -Code 'EUR' # Список имеющихся кодов валют floatrates-rub -Available function floatrates-rub {
PowerShell и онлайн сервисы. Погода (RP5.ru)
iNNOKENTIY21 11.11.2025
PowerShell функция Get-WeatherRP5rss для получения погоды с сервиса RP5 Примеры вызова Get-WeatherRP5rss с указанием id 5484 — Москва (восток, Измайлово) и переносом строки:. . .
PowerShell и онлайн сервисы. Погода (wttr)
iNNOKENTIY21 11.11.2025
PowerShell Функция для получения погоды с сервиса wttr Примеры вызова: Погода в городе Омск с прогнозом на день, можно изменить прогноз на более дней, для этого надо поменять запрос:. . .
PowerShell и онлайн сервисы. Валюта (ЦБР)
iNNOKENTIY21 11.11.2025
# Получение курса валют function cbr (] $Valutes = @('USD', 'EUR', 'CNY')) { $url = 'https:/ / www. cbr-xml-daily. ru/ daily_json. js' $data = Invoke-RestMethod -Uri $url $esc = 27 . . .
И решил я переделать этот ноут в машину для распределенных вычислений
Programma_Boinc 09.11.2025
И решил я переделать этот ноут в машину для распределенных вычислений Всем привет. А вот мой компьютер, переделанный из ноутбука. Был у меня ноут асус 2011 года. Со временем корпус превратился. . .
Мысли в слух
kumehtar 07.11.2025
Заметил среди людей, что по-настоящему верная дружба бывает между теми, с кем нечего делить.
Новая зверюга
volvo 07.11.2025
Подарок на Хеллоуин, и теперь у нас кроме Tuxedo Cat есть еще и щенок далматинца: Хочу еще Симбу взять, очень нравится. . .
Инференс ML моделей в Java: TensorFlow, DL4J и DJL
Javaican 05.11.2025
Python захватил мир машинного обучения - это факт. Но когда дело доходит до продакшена, ситуация не так однозначна. Помню проект в крупном банке три года назад: команда data science натренировала. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru