Форум программистов, компьютерный форум, киберфорум
C/C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.56/16: Рейтинг темы: голосов - 16, средняя оценка - 4.56
431 / 385 / 200
Регистрация: 12.08.2011
Сообщений: 1,610

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

26.07.2013, 13:46. Показов 3499. Ответов 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
3406 / 2177 / 354
Регистрация: 13.01.2012
Сообщений: 8,444
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
3406 / 2177 / 354
Регистрация: 13.01.2012
Сообщений: 8,444
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
3406 / 2177 / 354
Регистрация: 13.01.2012
Сообщений: 8,444
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
3406 / 2177 / 354
Регистрация: 13.01.2012
Сообщений: 8,444
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
3406 / 2177 / 354
Регистрация: 13.01.2012
Сообщений: 8,444
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
3406 / 2177 / 354
Регистрация: 13.01.2012
Сообщений: 8,444
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
3406 / 2177 / 354
Регистрация: 13.01.2012
Сообщений: 8,444
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
3406 / 2177 / 354
Регистрация: 13.01.2012
Сообщений: 8,444
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
3406 / 2177 / 354
Регистрация: 13.01.2012
Сообщений: 8,444
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
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru