C ++ Create BSTR at compile time / insert length into string at compile time?
Is it possible to use magic or TMP to insert length into a string at compile time?
For example:
const wchar_t* myString = L"Hello";
I would like the buffer to actually contain "[length] [string constant]".
I am using MSVC 2010 which is missing constexpr. I figured there must be some trick to make this work possible:
const wchar_t* myString = L"\x005Hello";
My attempt:
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");
This question seems to be related:
C ++ template strings consolation
But not a concat for two string constants, rather a constant generated from the length of the 2nd :)
source to share
You cannot create compile time BSTR
. BSTR
are defined as SysAllocString
family. If it is not that it is not BSTR
, but an impostor.
However, if the content is BSTR
known at compile time, you can have a global variable BSTR
and allocate it only once, avoiding the thousands of allocations you're worried about.
Ie, have a variable declared as BSTR
, but initialize it in line with SysAllocString
.
eg:.
BSTR bsHello = SysAllocString(L"Hello");
source to share
For BSTR
that are passed in read-only functions , I use this simple macro:
#define DECLARE_BSTR(Variable, String)\
struct \
{ \
uint32_t uLength; \
OLECHAR szData[sizeof(String)]; \
} \
Variable = {sizeof(String) - sizeof(OLECHAR), String};
Example:
ITaskFolder *pTaskFolder;
DECLARE_BSTR(static bstrTaskFolderName, L"\\");
if (SUCCEEDED(pTaskService->GetFolder(bstrTaskFolderName.szData, &pTaskFolder)))
Option that can be used instead BSTR
, i.e. without .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};
Example:
ITaskFolder *pTaskFolder;
DECLARE_BSTR(static bstrTaskFolderName, L"\\");
if (SUCCEEDED(pTaskService->GetFolder(bstrTaskFolderName, &pTaskFolder)))
source to share