returning D string from C++?

Marco Leise via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Aug 5 22:31:51 PDT 2017


Am Sat, 05 Aug 2017 20:17:23 +0000
schrieb bitwise <bitwise.pvt at gmail.com>:

>      virtual DString getTitle() const {
>          DString ret;
>          ret.length = GetWindowTextLength(_hwnd) + 1;
>          ret.ptr = (const char*)gc_malloc(ret.length, 0xA, NULL);
>          GetWindowText(_hwnd, (char*)ret.ptr, ret.length);
>          return ret;
>      }

In due diligence, you are casting an ANSI string into a UTF-8
string which will result in broken Unicode for non-ASCII window
titles. In any case it is better to use the wide-character
versions of Windows-API functions nowadays. (Those ending in
'W' instead of 'A'). Starting with Windows 2000, the core was
upgraded to UTF-16[1], which means you don't have to
implement the lossy conversion to ANSI code pages and end up
like this ...

                    [information loss]
           UTF-8 <-> Windows codepage <-> UTF-16
                  |                    |
                  in your code         inside Windows

... but instead directly pass and get Unicode strings like
this ...

           UTF-8 <-> UTF-16
                  |
                  in your code

string to zero terminated UTF-16:
http://dlang.org/phobos/std_utf.html#toUTF16z
zero terminated UTF-16 to string:
ptr.to!string() or just ptr[0..len] if known

Second I'd like to mention that you should have set
ret.length = GetWindowText(_hwnd, (char*)ret.ptr, ret.length);
Currently your length is anything from 1 to N bytes longer
than the actual string[2], which is not obvious because any
debug printing or display of the string stops at the embedded
\0 terminator.

[1] https://en.wikipedia.org/wiki/Unicode_in_Microsoft_Windows
[2]
https://msdn.microsoft.com/de-de/library/windows/desktop/ms633521(v=vs.85).aspx

-- 
Marco



More information about the Digitalmars-d-learn mailing list