Visual C ++ Создать BSTR во время компиляции / вставить длину в строку во время компиляции?

Возможно ли использовать макро-магию или TMP для вставки длины в строку во время компиляции?

Например:

const wchar_t* myString = L"Hello";

Я хотел бы, чтобы буфер фактически содержал «[length] [string constant]».

Я использую MSVC 2010, в котором отсутствует constexpr. Я подумал, что должен быть какой-то трюк, чтобы сделать эту работу максимально возможной:

const wchar_t* myString = L"\x005Hello";

Моя попытка пока:

template<int Size>
wchar_t* toBstr(const wchar_t* str)
{
#pragma pack(push)
#pragma pack(1)
struct BStr
{
int len;
wchar_t data[Size];
};
#pragma pack(pop)

static BStr ret;
ret.len = Size;

// don't want to have to copy here, how else could this work??
//ret.data = str;

return ret.data;
}

const wchar_t* m = toBstr<_countof(L"Hello")>(L"Hello");

Этот вопрос кажется связанным:

Конкатенация строк шаблона C ++

Но не конкат для двух строковых констант, а константа, сгенерированная из длины 2-й 🙂

1

Решение

Вы не можете создать время компиляции BSTR, BSTR определены для распределения SysAllocString и семья. Если это не так, это не BSTR, но самозванец.

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

Т.е. иметь переменную, объявленную как BSTR, но инициализировать его в строку, используя SysAllocString,

Например.:

BSTR bsHello = SysAllocString(L"Hello");
1

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

За BSTRкоторые передаются в функции только для чтения, Я использую этот простой макрос:

#define DECLARE_BSTR(Variable, String)\
struct                                \
{                                     \
uint32_t uLength;                 \
OLECHAR szData[sizeof(String)];   \
}                                     \
Variable = {sizeof(String) - sizeof(OLECHAR), String};

Пример:

ITaskFolder *pTaskFolder;
DECLARE_BSTR(static bstrTaskFolderName, L"\\");
if (SUCCEEDED(pTaskService->GetFolder(bstrTaskFolderName.szData, &pTaskFolder)))

Вариант, который можно использовать вместо BSTRто есть без .szData:

#define DECLARE_BSTR(Variable, String)               \
struct                                               \
{                                                    \
uint32_t uLength;                                \
OLECHAR szData[sizeof(String)];                  \
operator const OLECHAR *() const {return szData;}\
operator       OLECHAR *()       {return szData;}\
}                                                    \
Variable = {sizeof(String) - sizeof(OLECHAR), String};

Пример:

ITaskFolder *pTaskFolder;
DECLARE_BSTR(static bstrTaskFolderName, L"\\");
if (SUCCEEDED(pTaskService->GetFolder(bstrTaskFolderName, &pTaskFolder)))
1

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