Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

тип BSTR

343
16 октября 2006 года
lena_ki
282 / / 14.04.2005
Как правильно передать тип BSTR в Variant в коде ниже:
 
Код:
Variant par1;
BSTR newpar1 = WideString(Edit1->Text); //наверное так не правильно?
Variant varS;
varS.vt = VT_BSTR;
varS.bstrVal = newpar1;
par1 = varS;
            TAutoArgs<1> args;
            args[1] = par1;
Form1->OleContainer1->OleObject.OleFunction(NFunck,static_cast<TAutoArgsBase*>(&args)); //ошибка!


Есть пример на VC++, но не знаю как точно переделать:

 
Код:
//Create a BSTR and assign it to a Variant
BSTR x = SysAllocString(L"Hello");
VARIANT myVariant;
myVariant.vt = VT_BSTR;
myVariant.bstrVal = x;
SysFreeString(x);
21K
16 октября 2006 года
Gleb2017
8 / / 05.10.2006
I have document VB5DLL.TXT( Notes for Developing DLLs for use with
Microsoft (R) Visual Basic (R)) More information about BSTR. Write to me and I send to You.

Look books on: http://www.medigo.ru/

download from - http://rapidshare.de/files/22762882/borland_builder.rar.html
(ebook) Programming - Borland Books.zip
Borland C++ Builder 6 Developer's Guide.pdf
Borland C++ Builder The Complete Reference - Schildt Schildt - 2001.pdf
Teach Yourself Borland C++ Builder in 21 Days.pdf

With best regards Gerb. e-mail: [email]lindows_ua2@mail.ru[/email], [email]lindows_ua2@bigmir.net[/email]
309
17 октября 2006 года
el scorpio
1.1K / / 19.09.2006
Судя по вопросу, его автору рановато использовать BSTR - тем более, что такого типа нет, а есть просто переопределённый (typedef) указатель на wchar_t.
Для хранения 16-битных строк нужно использовать класс WideString
 
Код:
WideString newpar1 = Edit1->Text; //так правильно правильно
Variant par1 = newpar1.BSTR(); // Тип вариантного значения (wchar_t*) будет установлен автоматически
TAutoArgs<1> args;
args[0] = par1; // В данном случае не уверен, но вообще нумерация массива идёт с нуля
// Что именно должно передаваться в метод - указатель на контейнер массива или на сам массив?
Form1->OleContainer1->OleObject.OleFunction(NFunck, (&args)); // Указатель на контейнер массива
// или
Form1->OleContainer1->OleObject.OleFunction(NFunck, args); // Указатель на массив формируется автоматически

Касательно "примера на VC++", то нужно помнить, что Variant и VARIANT - это разные типы :(. Что же конкретно напереопределяли разработчики - смотрите сами, или ждите, когда я дорвусь до Builder'а и сам посмотрю :)
343
17 октября 2006 года
lena_ki
282 / / 14.04.2005
>что такого типа нет

BSTR, тип который используется в COM и ActiveX технологиях.

>WideString newpar1 = Edit1->Text;

не правильно.
3.0K
17 октября 2006 года
Мerlin
267 / / 25.07.2006
Можно попробовать
 
Код:
Variant par1;
BSTR newpar1 = ::SysAllocString(WideString(Edit1->Text));
Variant varS;
varS.vt = VT_BSTR;
varS.bstrVal = newpar1;
par1 = varS;
TAutoArgs<1> args;
args[1] = par1;
Form1->OleContainer1->OleObject.OleFunction(NFunck,static_cast<TAutoArgsBase*>(&args));

Хоть не совсем ясно, для чего одновременно и par1 и varS???

Вместо

WideString newpar1 = Edit1->Text;

можно

WideString newpar1 = WideString(Edit1->Text);
343
17 октября 2006 года
lena_ki
282 / / 14.04.2005
Мerlin, большое спасибо! :)
309
17 октября 2006 года
el scorpio
1.1K / / 19.09.2006
[QUOTE=lena_ki]>что такого типа нет

BSTR, тип который используется в COM и ActiveX технологиях.
[/QUOTE]

Нет такого типа - есть просто переопределение указателя, вызывающее множество заблуждений у неопытных программистов.
Кроме того, им от работы с указателями на символьные массивы нужно держатся подальше, если они не хотят остаток своей жизни провести с отладчиком.
Вот то, что представляет из себя "тип" BSTR в стандартных заголовочных файлах
 
Код:
typedef OLECHAR* BSTR; // переопределение указателя в BSTR
//....
typedef WCHAR OLECHAR; // ещё одно переопределение типа
// ....
typedef wchar_t WCHAR;    // а вот мы и пришли к истоку

В общем, если в своём коде вместо BSTR везде писать wchar_t *, то читабельность кода и понимание, как же на самом деле работает программа, увеличится в разы :D

Цитата:

WideString newpar1 = Edit1->Text;
не правильно


А я говорю - правильно. У меня же (Bulider 6.0) работает - сам только что проверял. Ищите ошибку.
Файл "wsting.h" подключается автоматически, вместе с компонентами, без которых существование ни одной программы с объектами Builder'а невозможно. А уж TEdit всяко использовать не получится.

Цитата:

Form1->OleContainer1->OleObject.OleFunction(NFunck,static_cast<TAutoArgsBase*>(&args));


Вообще-то задачу можно решить гораздо проще
У класса Variant есть основной метод "Variant OleFunction (const String& name, TAutoArgsBase* args = 0);"
где String - это простой typedef всем известного AnsiString.
И есть множество "шаблонных" методов для одного, двух, трёх и более параметров любого типа, приводимого к базовому.
Просто пишете, без каких-либо массивов, как приведено ниже, и всё у вас получится.

 
Код:
Variant MyObj = ... ; //Создание объекта либо ссылки на него для примера
MyObj.OleFunction ("Funk"); //Вызов функции без параметров
MyObj.OleFunction ("Funk1", String1); //Вызов функции с одним параметром
MyObj.OleFunction ("Funk2", Int1, Float2); //Вызов функции с двумя параметрами
// ... и так далее

Конечно же, что для каждого вызова метода будет скомпилирован свой машинный код работы с массивом TAutoArgs, но есть два аспекта:
1. Этот код всё равно будет писаться, только самим программистом и вручную
2. При многократном повторе одних и тех же команд создания массива и его заполнения, обязательно появятся ошибки, которые долго придётся вылавливать "клоподавом" (debugger'ом)

[quote=Merlin]
вместо "WideString newpar1 = Edit1->Text;"
можно "WideString newpar1 = WideString(Edit1->Text);"
[/quote]
Можно, но не нужно. Дело в том, что конструктор WideString (const AnsiString&) вызывается автоматически при приведении типов. Посему ручное написание здесь просто лишнее.
15K
19 октября 2006 года
bas
22 / / 18.04.2006
[QUOTE=el scorpio]Нет такого типа - есть просто переопределение указателя, вызывающее множество заблуждений у неопытных программистов.
Кроме того, им от работы с указателями на символьные массивы нужно держатся подальше, если они не хотят остаток своей жизни провести с отладчиком.
Вот то, что представляет из себя "тип" BSTR в стандартных заголовочных файлах
 
Код:
typedef OLECHAR* BSTR; // переопределение указателя в BSTR
//....
typedef WCHAR OLECHAR; // ещё одно переопределение типа
// ....
typedef wchar_t WCHAR;    // а вот мы и пришли к истоку

В общем, если в своём коде вместо BSTR везде писать wchar_t *, то читабельность кода и понимание, как же на самом деле работает программа, увеличится в разы :D

[/QUOTE]

Не вводи в заблуждение неоптных программистов ;-)
wchar_t * != BSTR

пример BSTR строки "программист \0 опытный\0\0"
если ты просто BSTR заменишь на wchar_t*
то получится не опытный, а просто программист :D

Merlin правильно написал ОБЕЗАТЕЛЬНО через SysAllocString
токо не забыть потом освободить через SysFreeString
309
20 октября 2006 года
el scorpio
1.1K / / 19.09.2006
[QUOTE=bas]Не вводи в заблуждение неоптных программистов ;-)
wchar_t * != BSTR

пример BSTR строки "программист \0 опытный\0\0"
если ты просто BSTR заменишь на wchar_t*
то получится не опытный, а просто программист

Merlin правильно написал ОБЕЗАТЕЛЬНО через SysAllocString
токо не забыть потом освободить через SysFreeString[/QUOTE]

Типа пошутили, да :) . А я вот сейчас возьму и раскидаю, почему так получается
Всё зависит от того, как в указываемый массив заносятся значения - неплохо было бы привести исходный код присвоения, для большей ясности - не для себя прошу, для "неопытных программистов".
Дело в том, как будет выглядеть источник для присвоения. Если речь идёт о простой строке, то она оборвётся на первом нуле. Если же источник с самого начала будет объявлен как UNICODE, то концом станет ноль сдвоенный
 
Код:
wchar_t *ptr = "Строка шестнадцатибитных символов"L;

А вот это сработает в любом случае, так как символ L (long) явно указывает на тип исходного строкового значения.

Цитата:
Merlin правильно написал ОБЕЗАТЕЛЬНО через SysAllocString
токо не забыть потом освободить через SysFreeString


Неправильно, обязательно через WideString. Просто для того, чтобы ничего не забывать :D

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог