How to ensure string compatibility In D?

Jonathan M Davis newsgroup.d at jmdavisprog.com
Wed Jan 23 14:12:09 UTC 2019


On Wednesday, January 23, 2019 5:42:55 AM MST FrankLike via Digitalmars-d-
learn wrote:
> On Wednesday, 23 January 2019 at 10:44:51 UTC, Jonathan M Davis
>
> wrote:
> > On Tuesday, January 22, 2019 2:49:00 PM MST bauss via
> > Digitalmars-d-learn wrote:
> >
> > toUTFz is the generic solution. toStringz exists specifically
>
> Error: template std.utf.toUTFz cannot deduce function from
>   argument types !()(string), candidates are:
> E:\D\DMD2\WINDOWS\BIN\..\..\src\phobos\std\utf.d(3070):
> std.utf.toUTFz(P)

As the documentation shows, toUTFz requires a target type just like
std.conv.to does. toUTF16z is a convenience wrapper around toUTFz which
specifies the target type as const(wchar)*.

> I have solved the problem in this way:
>
> import core.sys.windows.windows;
> import std.stdio;
> import std.string;
> import std.conv;
>
> void main()
> {
>   auto    strA_Z ="CD"w;
>   auto type = GetDriveType(tos(to!wstring(strA_Z[0])~":\\"));
>   writeln(to!wstring(strA_Z[0])~" is ",type);
> }
>
> private auto tos(T)(T str)
> {
>   version (ANSI)
>   {
>   writeln("ANSI");
>   return cast(const(char)*)(str);
>   }
>   else
>   {
>   writeln("Unicode");
>   return cast(const(wchar)*)(str);
>
>   }
> }
>
> Thanks.

std.conv.to will allow you to convert between string and wstring, but for
calling C functions, you still need the strings to be zero-terminated unless
the function specifically takes an argument indicating the number of
characters in the string. Strings in D are not zero-terminated, so
std.conv.to is not going to produce strings that work with C functions.
std.conv.to and std.utf.toUTFz solve different problems.

Also, strings of char in D are UTF-8, _not_ ANSI, so passing them to any of
the A functions from Windows is not going to work correctly. If you want to
do that, you need to use toMBSz and fromMBSz from std.windows.charset. But
really, there's no reason at this point to ever use the A functions. There
are frequently issues with them that the W functions don't have, and the W
functions actually support Unicode. The only real reason to use the A
functions would be to use an OS like Windows 98 which didn't have the W
functions, and D doesn't support such OSes. So, I would strongly discourage
you from doing anything with the A functions, let alone trying to write your
code so that it uses either the A or W functions depending on some argument.
That's an old Windows-ism that I wouldn't even advise using in C/C++ at this
point. It's just begging for bugs. And since D doesn't have the macros for
all of the various Windows functions for swapping between the A and W
versions of the functions like C/C++ does, you have to explicitly call one
or the other in D anyway, making it really hard to call the wrong one
(unlike in C/C++, where screwing up how your project is compiled can result
in accidentally using the A functions instead of the W functions). This
really sounds like you're trying to duplicate something from C/C++ that
doesn't make sense in D and really shouldn't be duplicated in D.

- Jonathan M Davis






More information about the Digitalmars-d-learn mailing list