From: George on
Hello everyone,


1.

BSTR is always wide character buffer. I do not know why the name of the
macro A2WBSTR is so special and add a needless 'W'?

For others dealing with BSTR, since it is already wide character buffer, 'W'
is no need. Like W2BSTR, and A2WSTR.

2.

What is differences between A2WBSTR and A2BSTR? Can not find answer from
search.


thanks in advance,
George
From: Igor Tandetnik on
George <George(a)discussions.microsoft.com> wrote:
> BSTR is always wide character buffer. I do not know why the name of
> the macro A2WBSTR is so special and add a needless 'W'?

I don't think it means much. ATL authors just needed a name for the
function, and A2BSTR was taken. Note that A2WBSTR is an undocumented
internal implementation detail.

Once upon a time, there existed a platform where OLECHAR was defined as
char (BSTR is a typedef for OLECHAR*). I believe it was some old Mac OS,
and you also had an option to build on Windows with OLE2ANSI macro
defined. You can still see in wtypes.h code like this:

#if defined(_WIN32) && !defined(OLE2ANSI)
typedef WCHAR OLECHAR;
#else
typedef char OLECHAR;
#endif

As far as I know, OLE2ANSI is not supported anymore, so nowadays you can
always assume BSTRs are Unicode.

> What is differences between A2WBSTR and A2BSTR? Can not find answer
> from search.

One is an internal undocumented function you shouldn't call directly.
The other is a documented function you are expected to use.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925


From: George on
After checking, my conclusion,

A2BSTR is for null terminated string input, and A2WBSTR can be non-null
terminated and assign an additional length field.

Correct?


// atlconv.h

inline BSTR A2BSTR(__in_opt LPCSTR lp) {return A2WBSTR(lp);}

_Check_return_ inline BSTR A2WBSTR(_In_opt_ LPCSTR lp, int nLen = -1)
{
if (lp == NULL || nLen == 0)
return NULL;
USES_CONVERSION_EX;
BSTR str = NULL;
#pragma warning(push)
#pragma warning(disable: 6385)
int nConvertedLen = MultiByteToWideChar(_acp_ex, 0, lp,
nLen, NULL, NULL);
#pragma warning(pop)
int nAllocLen = nConvertedLen;
if (nLen == -1)
nAllocLen -= 1; // Don't allocate terminating '\0'
str = ::SysAllocStringLen(NULL, nAllocLen);

if (str != NULL)
{
int nResult;
nResult = MultiByteToWideChar(_acp_ex, 0, lp, nLen, str, nConvertedLen);
ATLASSERT(nResult == nConvertedLen);
if(nResult != nConvertedLen)
{
SysFreeString(str);
return NULL;
}

}
return str;
}


regards,
George