c # — _bstr_r против _T (& quot; & quot;)

У меня есть библиотека .net, которая зарегистрирована как COM-объект, при импорте файла .tlb в проект C ++ я получаю такое объявление метода

  virtual HRESULT __stdcall GetBid (
/*[in]*/ BSTR symbol,
/*[out,retval]*/ double * pRetVal ) = 0;

для эквивалента .NET

double GetBid(string symbol);

сейчас я пытаюсь назвать это так

double bid;
ptr->GetBid(_T("AAPL"), &bid);

что не работает должным образом, потому что на стороне .NET строковый параметр на самом деле является пустой строкой.

Если я перейду на такой звонок

double bid;
ptr->GetBid(_bstr_t("AAPL"), &bid);

все работает как положено.

Почему оба вызова скомпилированы нормально, но результат отличается? Разве первый вызов не должен быть преобразован в правильный маршалинг строки?

Спасибо за любую под капотом информацию о магии БСТР 🙂

0

Решение

BSTR имеет 32-битную длину предшествующего строка. Таким образом, BSTR может содержать встроенные нули.

_T («AAPL») создает wchar_t * с завершающим нулем, но без префикса длины.

Однако оба они wchar_t *, поэтому вызов компилируется и преобразование не требуется. Тебе несколько повезло, потому что могло случиться что-то худшее, чем просто не натянуть веревку на другой стороне. Маршалер может взглянуть на счетчик _T («AAPL») обратно 32-битным, и, если повезет, получит значение длинной длины reeeeaalally, что было бы плохо. 🙂

Вы получите автоматическое преобразование, если параметр будет определен как _bstr_t, так как это вызовет конструктор _bstr_t (wchar_t *).

3

Другие решения

Так как BSTR является указателем на строку широких символов, но это не значит, что вы можете просто назначить простую const wchar_t * string. Для работы с BSTR необходимо использовать несколько системных функций, строка SysAllocString () для создания БСТР. Класс _bstr_t инкапсулирует все это

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector