Hi Guys,

I am trying to serialise a SAFEARRAY to a string.

I tried this:

SAFEARRAY* content;
...
CComVariant value( content );
value.ChangeType( VT_BSTR );
BSTR bstrValue = value.bstrVal;
_bstr_t temp;
temp.Assign(bstrValue);
std::string content(temp);

However I get this error:
error C2040: 'content' : 'std::string' differs in levels of indirection from 'SAFEARRAY *'


Any advice??

Thanks in advance,
Rob

VT_BSTR can not be directly converted to std::string because a BSTR is UNICODE wchar_t*, not char*. You have to use one of the conversion functions. Here is an example, when compiled with VC++ 2008 Express you must compile for UNICODE (the default)

#include <windows.h>
#include <tchar.h>
#include <string>
#include <iostream>
using namespace std;

int main(int argc, char* argv[])
{
	// allocate a BSTR string
	BSTR b = SysAllocString(_TEXT("Hello World"));
	std::string str;
	// get length of the string.  Number of bytes
	// allocated to BSTR divided by size of wchar_t
	// is the number of characters in the BSTR.

	size_t sz = (*(long *)(b-2))/sizeof(wchar_t)+1;
	char *buf = new char[sz];
	// convert from wchar_t* to char*
	wcstombs(buf, b, sz);
	str = buf;
	cout << sz << "\n" << str << "\n";


	return 0;
}

VC++ 6.0 has a macro _L("text") that forces a char* to wchar*, but I could not find it in VC++ 2008 Express, hence the use of _TEXT and requirement to compile for UNICODE. But for the OPs purpose this is just adademic because his strings are (presumably) already BSTR UNICODE.

BSTRs can contain other binary blobs as well -- there is no requirement that they be null-terminated UNICODE strings. So if the BSTR contains anything other than a standard string then the code I posted above will not work correctly, nor should you attempt to assign the blobs to a std::string object.

This article has been dead for over six months. Start a new discussion instead.