How to convert wstring to Unistring in macOS
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2018-03-16
04:47 AM
- last edited on
2022-12-06
01:44 PM
by
Daniel Kassai
For example, when I have the following code :
const GS::UniString a = L"xxx";or
DGTreeViewSetItemText(dialogID, itemID, CS,L"xxx");It is no problem if I develop in windows
but in macOS it will show error: have no viable conversion for const wchar_t[4] to GS::UniString
Thanks for helping!!!!
- Labels:
-
Add-On (C++)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2018-03-16 12:21 PM
1) If this is text that is meant to be user-readable, it would be better to store it in a string resource rather than hard-coding it. Then the encoding can be dealt with by ARCHICAD and your add-on will be far easier to localise.
2) Use a prefix to specify the encoding, e.g. for utf-8:
GS::UniString a(u8"xxx", CC_UTF8);
Central Innovation
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2018-03-26 02:29 PM
You may use u8"my string" literals on both platforms, or you may convert your L"my string" constants into appropriate format for every platform.
I'd implement it like that:
#ifndef SL std::string ToUtf8(const std::wstring& widestring) { size_t widesize = widestring.length(); if (sizeof(wchar_t) == 2) { size_t utf8size = 3 * widesize + 1; char* utf8stringnative = new char[utf8size]; const UTF16* sourcestart = reinterpret_cast<const UTF16*>(widestring.c_str()); const UTF16* sourceend = sourcestart + widesize; UTF8* targetstart = reinterpret_cast<UTF8*>(utf8stringnative); UTF8* targetend = targetstart + utf8size; ConversionResult res = ConvertUTF16toUTF8 (&sourcestart, sourceend, &targetstart, targetend, strictConversion); if (res != conversionOK) { delete [] utf8stringnative; throw std::exception("La falla!"); } *targetstart = 0; std::string resultstring(utf8stringnative); delete [] utf8stringnative; return resultstring; } else if (sizeof(wchar_t) == 4) { size_t utf8size = 4 * widesize + 1; char* utf8stringnative = new char[utf8size]; const UTF32* sourcestart = reinterpret_cast<const UTF32*>(widestring.c_str()); const UTF32* sourceend = sourcestart + widesize; UTF8* targetstart = reinterpret_cast<UTF8*>(utf8stringnative); UTF8* targetend = targetstart + utf8size; ConversionResult res = ConvertUTF32toUTF8 (&sourcestart, sourceend, &targetstart, targetend, strictConversion); if (res != conversionOK) { delete [] utf8stringnative; throw std::exception("La falla!"); } *targetstart = 0; std::string resultstring(utf8stringnative); delete [] utf8stringnative; return resultstring; } else { throw std::exception("La falla!"); } return ""; } #ifdef _WIN32 #define SL(str) str #else #define SL(str) ToUtf8(str).c_str() #endif #endif const GS::UniString a = SL(L"xxx"); // This will compile well now.You may move the code into a separate header file and include it everywhere you want to initialize UniString with a string literal. Just remove the last line with a comment.
Like that:
#include "sl.h" const GS::UniString a = SL(L"xxx"); // This will compile well now.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2018-03-26 07:25 PM
chebum wrote:A few observations:
UniString is implemented differently on Mac: it stores characters in UTF-8 encoding on Mac(e.g. 1-byte per character). On Windows it uses wchar_t which is 2-bytes per character. Thus const GS::UniString a = L"xxx"; will compile on Windows, but will fail on Mac. Graphisoft changed implementation of UniString somewhere between AC15 and AC21. In older versions it used wchart_t.
- 1) All text encoding is UTF-8 from AC21 – from the documentation:
All C strings (char *, char []) are now UTF-8 encoded.
2) Text encoding is not the same as the number of bytes consumed by a character. Many different encodings will use the same number of bytes, but are not equivalent. Constructing a UniString from wchar_t only works on Windows because it's commonly assumed to be UTF-16. It's a bad idea if you intend to write cross-platform code.
3) UTF-8 doesn't have a fixed number of bytes per character. The only thing that can be said in relation to 8-bit encodings is that old string methods assuming fixed 8-bit characters with null termination won't crash on UTF-8 text.
chebum wrote:I'd strongly recommend using the mechanisms provided by GS. Writing your own methods for solved problems just wastes time and opens you up to more bugs and future migration problems.#include "sl.h" const GS::UniString a = SL(L"xxx"); // This will compile well now.
Central Innovation
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
2023-01-12 09:03 PM
Ralph, your expression throws me in an "Excess elements in scalar initializer" error.
Knowing that I am not familiar with the ACAPI expressions, can you tell me what am I doing wrong?
Thank you
Nic