【问题标题】:Converting from const char* to Swift string从 const char* 转换为 Swift 字符串
【发布时间】:2016-08-14 19:29:27
【问题描述】:

我有一个 c 函数,我从一个返回 const char* 的桥接头访问它:

const char* get_c_string();

然后我尝试将其转换为 Swift 字符串:

let str = String.fromCString(UnsafePointer<Int8>(get_c_string()))
print(str)

...但它只是打印垃圾:

Optional("\u{14}\0\0")

我可以找到如何将 Swift 字符串传递给 C,但不能反过来。如何将 const char* 转换为 Swift 字符串?

谢谢!

【问题讨论】:

  • 这个字符串有特殊字符?
  • 不,它只是一个标准的const char* c 字符串(来自std::string
  • 您的示例中有两个不同的函数get_c_stringcall_hi。除此之外,您的转换方法应该有效。注意指针转换不是必须的:let str = String.fromCString(get_c_string()).
  • typo - 调用与原型匹配,因此调用了正确的函数。它看起来像一个编码问题,但不确定是什么。
  • 也许 get_c_string() 返回一个局部变量的内容(函数返回时变为无效)?您必须确保返回的指针在函数返回时仍然有效(例如 malloc 内存或 strdup 字符串)。你的 Swift 代码是正确的。

标签: c swift


【解决方案1】:

您的 Swift 代码是正确的,您可以将其稍微缩短为

// Swift 2:
let str = String.fromCString(get_c_string())
// Swift 3:
let str = String(cString: get_c_string())

但是,您必须确保从 C 函数返回的指针 函数返回时仍然有效。举个例子

const char* get_c_string() {
    char s[] = "abc";
    return s;
}

返回本地堆栈变量的地址,这是未定义的行为。

您可能必须复制字符串(然后考虑何时 以及在哪里释放内存)。

【讨论】:

  • 此 API 使用不再是最新的。编译器报告:“请改用 String.init?(validatingUTF8:)。请注意,它不再接受 NULL 作为有效输入。还可以考虑使用 String(cString:),这将尝试修复格式错误的代码单元。”
  • @sandover:使用当前发布版本 Xcode 7.3/Swift 2.2,上述代码仍然可以编译,不会出现警告或错误。 API 似乎在 Swift 3 中发生了变化,所以一旦正式发布,我将不得不更新答案。
  • 我希望这是我遇到的问题,但我认为不是。如果您在这里有类似的见解,想听听您的想法:stackoverflow.com/questions/37776867/…
猜你喜欢
  • 1970-01-01
  • 2014-05-16
  • 2021-09-05
  • 1970-01-01
  • 2020-05-08
  • 2013-02-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多