从C ++ std :: string&获取unichar *在Objective-C ++中创建非空NSString [英] Get unichar * from a C++ std::string& to create a nonnull NSString in Objective-C++

查看:154
本文介绍了从C ++ std :: string&获取unichar *在Objective-C ++中创建非空NSString的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些可以封装现有C ++库的Objective-C ++. C ++库有时会为我提供要转换为nonnull NSString s的std::string&参数.除了-initWithCharactersNoCopy:length:freeWhenDone:-initWithCharacters:length:,几乎所有NSString初始化程序都返回nullable NSString.但是,这两个都需要unichar *,但是std::string.c_str()返回char *.

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 *.

如何从C ++ std::string获取unichar *,以便创建NSString * _Nonnull?

How can I get a unichar * from a C++ std::string so that I can create an NSString * _Nonnull ?

非重复

其他问题只是想从std::string转换为NSString.我想知道是否有可能不生成null NSString *而这样做,可能是通过调用std::string上的方法来获取unichar *的. std::wstring_convert 看起来很有希望,但我不是C ++开发人员,所以我还不知道如何开始.

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.

可能的解决方案

进一步研究后,我发现std::string只是一个std::basic_string<char>,似乎您可以定义自己的std::basic_string.我找到了转换为std::wstring :

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());

因此我将其调整为std::basic_string<unichar>,并且编译良好:

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);
}

我不介意从std::string转换为std::basic_string<unichar>会执行不必​​要的复制,并且我想一旦我对C ++内存所有权规则有了更多的了解,就可以将上述代码更改为使用-[NSString initWithCharactersNoCopy:length:freeWhenDone:].

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.

可能的解决方案不好

乔·格罗夫(Joe Groff)在推特上说:

这将进行逐字节映射.它可能适用于ASCII,但 将为您提供任何Unicode的垃圾.

That's going to do a byte-by-byte mapping. It may work for ASCII but will give you garbage for any Unicode.

推荐答案

让我们再试一次,看看它是否对您有帮助.您已根据问题的建议编辑了问题,并添加了以下内容:

Let's try again, see if it helps you. You have edited the question in response to the suggestion it is a duplicate and added:

其他问题只是想从std::string转换为NSString.我想知道是否可以不生成null NSString * ...

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 *...

直接答案:否

原因很简单:即使键入std::string,Objective-C库也不能假定传递给它的任何指针都引用了有效编码的C字符串.

The reason is straightforward: The Objective-C library cannot assume that any pointer passed to it references a validly encoded C string, even if that pointer is typed std::string.

现在,您可能会非常有信心,您的C ++代码将永远不会传递给您无效编码的字符串-并可以说,这种信心是合理的(但毕竟是C ++ ;-)),因此您可以相信结果为空永远不会发生,但这不会改变Objective-C库无法假定不会的事实.

Now you may be very confident that your C++ code will never pass you an invalidly encoded string – and it can be argued that confidence is reasonable (but then it is C++ after all ;-)) – and so believe the null result will never happen, but that does not change the fact that the Objective-C library cannot assume it won't.

DIY答案:是

尝试避免null,例如通过尝试将std::string转换为unichar *等,就可以避免该问题-某些地方的某些代码必须处理编码检查,否则可能会返回无效编码的NSString.

Trying to avoid the null, e.g. by trying to convert the std::string into a unichar * etc. as you have considered, just avoids the issue - some piece of code somewhere has to deal with checking the encoding or risk returning an invalidly encoded NSString.

虽然有可能这样做,但与DIY方法相比,这将涉及更多的问题,并且可能使您不知道针对无效编码返回了什么:只需处理null,请在源代码处自行返回并替换为其他的东西.例如:

While it might be possible to do this it will both be more involved, and may leave you not knowing what is returned for invalid encodings, compared to the DIY approach: just deal with the null return yourself at source and replace it by something else. For example:

std::string someCstring;

NSString *convertedString = @(someCstring.c_str()) ?: @"ERROR: C string is invalid UTF8";

这里convertedString永远不会是nil.

(如果您的C字符串不是UTF8,则需要使用另一个采用编码的NSString初始化程序.)

(If your C string is not UTF8 you will need to use another NSString initialiser which takes an encoding.)

HTH

这篇关于从C ++ std :: string&amp;获取unichar *在Objective-C ++中创建非空NSString的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆