【问题标题】:Use a Char array from Swift in C在 C 中使用来自 Swift 的 Char 数组
【发布时间】:2016-08-06 02:39:27
【问题描述】:

目前我有三个文件

main.swift

var dog = Dog()

dog.age = 12
dog.name = "H" // This is the non workable code

CTester.c

#include <stdio.h>

struct Dog {
    int age;
    char name[10];
} Dog;

和 C Test-Bridging-Header

#import "CTester.c"

我试图在 Swift 中使用 C 结构,但是,Char 数组在 Swift 中显示为 10 个 Int8 的数组。如何获取 Swift 字符串并将其分配给 char 数组?

【问题讨论】:

  • C 数组作为 tuples 导入到 Swift 中,使用起来很不方便。这对stackoverflow.com/questions/27461904/… 有帮助吗?
  • 顺便说一句,您通常会导入 h 文件,而不是 c 文件。
  • 感谢 Martin,它帮助我理解了它为什么要做元组,这也是一个很好的链接!我也许可以使用那里的信息来弄清楚如何做我想做的事情。是的,我知道我应该使用 H 文件作为一种良好的做法,但这是一个如此小的测试,因此它不会进行。

标签: c swift


【解决方案1】:

所以,你可以像这样为你的Dog 写一些扩展:

斯威夫特 2

extension Dog {
    var Name: String {
        mutating get {
            return withUnsafePointer(&self.name) {namePtr in
                let charPtr = UnsafePointer<CChar>(namePtr)
                //Sorry, this code may crash here...
                return String(CString: charPtr, encoding: NSUTF8StringEncoding)!
            }
        }
        set {
            withUnsafeMutablePointer(&self.name) {namePtr in
                let charPtr = UnsafeMutablePointer<CChar>(namePtr)
                let size = sizeofValue(self.name)
                strncpy(charPtr, newValue, size - 1)
                charPtr[size - 1] = 0
            }
        }
    }
}

Swift 3(使用 Xcode 8 beta 4 测试)

extension Dog {
    var Name: String {
        mutating get {
            return withUnsafePointer(&self.name) {namePtr in
                let charPtr = UnsafePointer<CChar>(namePtr)
                //The result may contain the Unicode replacement character ("\u{FFFD}")
                return String(cString: charPtr)
            }
        }
        set {
            withUnsafeMutablePointer(&self.name) {namePtr in
                let charPtr = UnsafeMutablePointer<CChar>(namePtr)
                let size = sizeofValue(self.name)
                strncpy(charPtr, newValue, size - 1)
                charPtr[size - 1] = 0
            }
        }
    }
}

在 Martin R 的评论中看到the linked thread,可能还有一些改进的空间...... (特别是使用strlcpy 可以减少代码大小并提高安全性。请检查一下。)

但无论如何,它的工作原理是:

dog.Name = "H"
print(dog.Name) //->H

我发现 Name 的 getter 可能会使您的应用崩溃... “它有效”的限制是您只能存储 ASCII 字符。

【讨论】:

  • 吸气剂似乎对我不起作用。它会打印字符串的地址和类型,如下所示: (0x00000001003b2914, Unicode (UTF-8))
  • @StephenKac,抱歉,我无法重现相同的结果。你没有我的代码的任何部分拼写错误吗?我已经使用 Xcode 7.3.1 检查了我在 OS X 项目和 iOS 项目中的代码,并且在这两个项目中都可以正常工作。我可能遗漏了一些东西,所以我尝试了很多东西,但我找不到像Unicode (UTF-8) 这样的东西。
  • @StephenKac,好的,我将附加我的代码的 Swift 3 版本。
  • @MartinR,谢谢。我认为我的代码在手动终止 NUL 方面效果很好。但是您的建议似乎要好得多。
  • 它在通过 lldb 调试器查看时有效,但如果您尝试将其打印到屏幕上,它不会打印单个字符。
猜你喜欢
  • 1970-01-01
  • 2020-10-06
  • 2016-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-21
  • 1970-01-01
  • 2017-08-09
相关资源
最近更新 更多