I have some Objective-C++ that wraps an existing C++ library. The C++ library occasionally gives me std::string& parameters that I want to convert into nonnull NSStrings. Almost all of the NSString initializers return nullable NSStrings except: -initWithCharactersNoCopy:length:freeWhenDone: and -initWithCharacters:length:. However, both of those require unichar *, but std::string.c_str() returns char *.
How can I get a unichar * from a C++ std::string so that I can create an NSString * _Nonnull ?
Not a duplicate
Other questions simply want to convert from std::string to NSString. I want to know if it's possible to do so without producing a null NSString *, possibly by calling methods on std::string to get unichar *. std::wstring_convert looks promising, but I'm not a C++ developer, so I don't know how to get started with that yet.
Possible solution
After researching further, I learned that std::string is just a std::basic_string<char>, and it seems like you can define your own std::basic_strings. I found a similar example that converts to std::wstring:
// std::string -> std::wstring
std::string s("string");
std::wstring ws;
ws.assign(s.begin(), s.end());
So I adapted it to std::basic_string<unichar>, and it compiles fine:
void Foo(const std::string& bar) {
std::basic_string<unichar> barUnichar;
barUnichar.assign(bar.begin(),
bar.end());
NSString * _Nonnull barNSString =
[NSString stringWithCharacters:barUnichar.c_str()
length:barUnichar.length()];
NSLog(@"bar: %@", bar);
}
I don't mind that converting from std::string to std::basic_string<unichar> performs a needless copy, and I imagine I can change the above code to use -[NSString initWithCharactersNoCopy:length:freeWhenDone:] once I learn more about C++ memory ownership rules.
Possible solution is no good
That's going to do a byte-by-byte mapping. It may work for ASCII but will give you garbage for any Unicode.