Convert wchar* to wstring?

tsbockman via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Tue Apr 5 00:10:50 PDT 2016


On Tuesday, 5 April 2016 at 01:21:55 UTC, Thalamus wrote:
> When the message parameter is wchar*, wstring info = 
> to!wstring(message) populates the string with the _address_ of 
> the wchar*. So when message was in the debugger as 
> 0x00000000035370e8 L"Writing Exhaustive unit tests is 
> exhausting.", the wstring info variable ended up as {length=7 
> ptr=0x000000001c174a20 L"35370E8" }.

`wchar*` is a raw pointer. D APIs generally expect a dynamic 
array - also known as a "slice" - which packs the pointer 
together with an explicit `length` field. You can easily get a 
slice from a pointer using D's convenient slicing syntax:
     https://dlang.org/spec/arrays.html#slicing

     wchar* cw;
     size_t cw_len; // be sure to use the right length, or you'll 
suffer buffer overruns.

     wchar[] dw = cw[0 .. cw_len];

Slicing is extremely fast, because it does not allocate any new 
heap memory: `dw` is still pointing to the same chunk of memory 
as cw. D APIs that work with text will often accept a mutable 
character array like `dw` without issue.

However, `wstring` in D is an alias for `immutable(wchar[])`. In 
the example above, `dw` cannot be immutable because it is reusing 
the same mutable memory chunk as `cw`. If the D code you want to 
interface with requires a real `wstring`, you'll need to copy the 
text into a new immutable memory chunk:

     wstring wstr = dw.idup; // idup is short for "immutable 
duplicate"

`idup` will allocate heap memory, so if you care about 
performance and memory usage, don't use it unless you actually 
need it.

You can also combine both steps into a one-liner:

     wstring wstr = cw[0 .. cw_len].idup;


More information about the Digitalmars-d-learn mailing list