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 :)

+1


source to share


2 answers


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");

      

+1


source


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)))

      

+1


source







All Articles