How to convert Platform::String to char*?
Platform::String::Data()
will return a wchar_t const*
pointing to the contents of the string (similar to std::wstring::c_str()
). Platform::String
represents an immutable string, so there's no accessor to get a wchar_t*
. You'll need to copy its contents, e.g. into a std::wstring
, to make changes.
There's no direct way to get a char*
or a char const*
because Platform::String
uses wide characters (all Metro style apps are Unicode apps). You can convert to multibyte using WideCharToMultiByte
.
Convert Platform::String to std::string
Edit: see this answer for a better portable solution.
The problem is that std::string
only holds 8-bit character data and your Platform::String^
holds Unicode data. Windows provides functions WideCharToMultiByte
and MultiByteToWideChar
to convert back and forth:
std::string make_string(const std::wstring& wstring)
{
auto wideData = wstring.c_str();
int bufferSize = WideCharToMultiByte(CP_UTF8, 0, wideData, -1, nullptr, 0, NULL, NULL);
auto utf8 = std::make_unique<char[]>(bufferSize);
if (0 == WideCharToMultiByte(CP_UTF8, 0, wideData, -1, utf8.get(), bufferSize, NULL, NULL))
throw std::exception("Can't convert string to UTF8");
return std::string(utf8.get());
}
std::wstring make_wstring(const std::string& string)
{
auto utf8Data = string.c_str();
int bufferSize = MultiByteToWideChar(CP_UTF8, 0, utf8Data, -1, nullptr, 0);
auto wide = std::make_unique<wchar_t[]>(bufferSize);
if (0 == MultiByteToWideChar(CP_UTF8, 0, utf8Data, -1, wide.get(), bufferSize))
throw std::exception("Can't convert string to Unicode");
return std::wstring(wide.get());
}
void Test()
{
Platform::String^ str = L"विकास, વિકાસ, ਵਿਕਾਸ, Vikas";
std::wstring wsstr(str->Data());
auto utf8Str = make_string(wsstr); // UTF8-encoded text
wsstr = make_wstring(utf8Str); // same as original text
}
How to convert from char to Platform::String^ (C++/CLI)
ref new Platform::String(&ch, 1);
C++/CX - I need to pass a Platform::String into a method that takes a const char*?
Disclaimer: I know little about C++/CX, and I'm basing the answer on the documentation here.
The String
class contains 16-bit Unicode characters, so you can't directly get a pointer to 8-bit char
-typed characters; you'll need to convert the contents.
If the string is known to only contain ASCII characters, then you can convert it directly:
String s = whatever();
std::string narrow(s.Begin(), s.End());
function_requiring_cstring(narrow.c_str());
Otherwise, the string will need translating, which gets rather hairy. The following might do the right thing, converting the wide characters to multi-byte sequences of narrow characters:
String s = whatever();
std::wstring wide(s.Begin(), s.End());
std::vector<char> buffer(s.Length()+1); // We'll need at least that much
for (;;) {
size_t length = std::wcstombs(buffer.data(), wide.c_str(), buffer.size());
if (length == buffer.size()) {
buffer.resize(buffer.size()*2);
} else {
buffer.resize(length+1);
break;
}
}
function_requiring_cstring(buffer.data());
Alternatively, you may find it easier to ignore Microsoft's ideas about how strings should be handled, and use std::string
instead.
Related Topics
Pointer Array and Sizeof Confusion
How to Set the Cout Locale to Insert Commas as Thousands Separators
Implementing a Std::Vector Like Container Without Undefined Behavior
Vector<Unique_Ptr<A> > Using Initialization List
C++11 Std::Mutex in Visual Studio 2012 Deadlock When Locked from Dllmain()
Boost Asio - How to Write Console Server
Are Variadic MACros Nonstandard
Does C++11 Allow Dollar Signs in Identifiers
Why Must Virtual Base Classes Be Constructed by the Most Derived Class
Can Void* Be Used to Store Function Pointers
What Is the Class Keyword Before a Function Argument
Load 32-Bit Shared Library from 64-Bit Application
Using Bind1St for a Method That Takes Argument by Reference
Conversion from Derived** to Base**
How to Initialize the Reference Member Variable of a Class
Adding Signals/Slots (Qobject) to Qgraphicsitem: Performance Hit