How to convert "string" to const(wchar)* ?

Jonathan M Davis newsgroup.d at jmdavisprog.com
Wed Jan 29 06:53:15 UTC 2020


On Tuesday, January 28, 2020 10:17:03 PM MST Marcone via Digitalmars-d-learn 
wrote:
> How to convert "string" to const(wchar)* ?
> The code bellow is making confuse strange characters.
>
> cast(wchar*) str

Of course it is. string is immutable(char)[], and the characters are in
UTF-8. immutable(wchar)[] would would be UTF-16. Even casting between those
two types would result in nonsense, because UTF-8 and UTF-16 are different
encodings. Casting between array or pointer types basically causes one type
to be interpreted as the other. It doesn't convert the underlying data in
any fashion. Also, strings aren't null-terminated in D, so having a pointer
to a random string could result in a buffer overflow when you try to iterate
through the string via pointer as is typical in C code. D code just uses the
length property of the string.

I assume that with const(wchar)*, you want it to be a null-terminated string
of const(wchar). For that, what you basically need is a const(wchar)[] with
a null terminator, and then you need to get a pointer to its first
character. So, if you were to do that yourself, you'd end up with something
like

wstring wstr = to!wstring(str) ~ '\0';
const(wchar)* cwstr = wstr.ptr;

or more likely

auto = to!wstring(str) ~ '\0';
auto cwstr = wstr.ptr;

The function in the standard library for simplifying that is toUTF16z:

https://dlang.org/phobos/std_utf.html#toUTF16z

Then you can just do

auto cwstr = str.toUTF16z();

However, if you're doing this to pass a null-terminated string of UTF-16
characters to a C program (e.g. to the Windows API), be aware that if that
function stores that pointer anywhere, you will need to also store it in
your D code, because toUTF16z allocates a dynamic array to hold the string
that you're getting a pointer to, and if a C function holds on to that
pointer, the D GC won't see that it's doing that. And if the D GC doesn't
see any references to that array anywhere, it will likely collect that
memory. As long as you're passing it to a C function that just operates on
the memory and returns, it's not a problem, but it can definitely be a
problem if the C function stores that pointer even after the function has
returned. Keeping a pointer to that memory in your D code fixes that
problem, because then the D GC can see that that memory is still referenced
and thus should not be collected.

- Jonathan M Davis





More information about the Digitalmars-d-learn mailing list