views:

139

answers:

3

I'm making a firefox extension (nsACString is from mozilla) but LoadLibrary expects a LPCWSTR. I googled a few options but nothing worked. Sort of out of my depth with strings so any references would also be appreciated.

+1  A: 

Firstly note: LoadLibrary need not accept a LPWSTR. Only LoadLibraryW does. You may call LoadLibraryA directly (passing a narrow LPCSTR) and it will perform the translation for you.

If you choose to do it yourself however, below is one possible example.

nsACString sFoo = ...;  // Some string.
size_t len = sFoo.Length() + 1;
WCHAR *swFoo = new WCHAR[len];
MultiByteToWideChar(CP_ACP, 0, sFoo.BeginReading(), len - 1, swFoo, len);
swFoo[len - 1] = 0;  // Null-terminate it.

...

delete [] swFoo;
Alex
You could be much better off using std::vector<WCHAR> instead of manually managing buffer lifetime.
sharptooth
Alex
Well this worked, thanks. I still have no idea why...
MercerKernel
@Alex: Well, by the standard reserve() isn't enough. You have to actually set the size of the vector: `std::vector<WCHAR> vecFoo(len);`. Then `vecFoo[0]` ... `vecFoo[len-1]` is contiguous storage.
Steve Jessop
A: 

nsACString a;

const char* pData; PRUint32 iLen = NS_CStringGetData(a, &pData);

João Augusto
+2  A: 

It depends whether your nsACString (which I'll call str) holds ASCII or UTF-8 data:

ASCII

std::vector<WCHAR> wide(str.Length()+1);
std::copy(str.beginReading(), str.endReading(), wide.begin());
// I don't know whether nsACString has a terminating NUL, best to be sure
wide[str.Length()] = 0;
LPCWSTR newstr = &wide[0];

UTF-8

// get length, including nul terminator
int len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, 
    str.BeginReading(), str.Length(), 0, 0);
if (len == 0) panic(); // happens if input data is invalid UTF-8

// allocate enough space
std::vector<WCHAR> wide(len);

// convert string
MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, 
    str.BeginReading(), str.Length(), &wide[0], len)

LPCWSTR newstr = &wide[0];

This allocates only as much space as is needed - if you want faster code that potentially uses more memory than necessary, you can replace the first two lines with:

int len = str.Length() + 1;

This works because a conversion from UTF-8 to WCHAR never results in more characters than there were bytes of input.

Steve Jessop