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;