Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在Swift中复制指向数组的指针?_C_Swift_Pointers_Unsafe Pointers - Fatal编程技术网

C 如何在Swift中复制指向数组的指针?

C 如何在Swift中复制指向数组的指针?,c,swift,pointers,unsafe-pointers,C,Swift,Pointers,Unsafe Pointers,我基本上是在尝试将C结构封装到Swift类中 Swift类具有C结构类型的实例属性 C结构包含几个类型为const char*的属性 为了给结构赋值,我为每个属性编写了getter和setter: 公共类MyClass:NSObject{ 私有变量配置=c_结构_配置() } //MyClass的函数 //f.ex。关于“注册URI”: 私有(集合)公共var注册URI:字符串{ 得到{ 返回字符串(cString:configuration.reg_uri) } 设置{ if(configu

我基本上是在尝试将C结构封装到Swift类中

Swift类具有C结构类型的实例属性

C结构包含几个类型为
const char*
的属性

为了给结构赋值,我为每个属性编写了getter和setter:

公共类MyClass:NSObject{
私有变量配置=c_结构_配置()
}
//MyClass的函数
//f.ex。关于“注册URI”:
私有(集合)公共var注册URI:字符串{
得到{
返回字符串(cString:configuration.reg_uri)
}
设置{
if(configuration.reg_uri!=nil){
configuration.reg_uri.deallocate()
}
设maxLength=newValue.count+1//+1表示NULL
var buffer:[CChar]=[CChar](未配置缓冲指针。分配(容量:maxLength))
guard newValue.getCString(&buffer,maxLength:maxLength,编码:.utf8)==true{
fatalError(“无法为帐户配置注册表uri分配内存”)
}
//“配置”是实例属性(见上文)
//reg_uri的类型为char const*
configuration.reg_uri=UnsafePointer(缓冲区)
}
}
但是,这种方法会导致奇怪的崩溃和错误报告,抱怨指针重叠范围(
致命错误:UnsafeMutablePointer.initialize overlapping range

我知道每当设置字符串时,我都在释放和分配内存,这可能不是很有效。不过,到目前为止,我还没有找到更好的解决办法


这里出了什么问题(或者这是对的,我做了一个错误的假设,我必须去其他地方搜索)?

您的解决方案有几个问题

首先,使用
String.count
进行计数以获得底层C缓冲区的大小是不明智的。原因是
String.count
返回字符串的实际字符数,而不是用于表示字符串的字节数。并非所有字符都适合
Int8
(也称为
CChar
)的256位。因此,如果尝试使用非ascii字符设置属性,代码可能会崩溃。最好使用
String.utf8CString
属性,该属性返回
CChar
的连续数组

其次,由于您的缓冲区是在setter中分配的,因此当setter返回时,它将被释放(Swift数组是值类型的实例,其生命周期受堆栈限制)。这意味着,当setter返回时,与
缓冲区
的基相对应的指针实际上无效。我怀疑这就是您报告的错误在运行时发生的原因

最后,请不要在guards和if语句中测试
true

以下是更正的版本:

var registrationUri: String {
  get {
    return String(cString: reg_uri)
  }
  set {
    if (reg_uri != nil) {
      reg_uri.deallocate()
    }

    newValue.withCString { cString in
      // No need to add 1, newValue.utf8CString already has the correct buffer capacity.
      let capacity = newValue.utf8CString.count
      let buffer: UnsafeMutablePointer<Int8> = .allocate(capacity: capacity)
      buffer.assign(from: cString, count: capacity)
      reg_uri = UnsafePointer(buffer)
    }
  }
}

// ...

myInstance.registrationUri = "こんいちは"
print(myInstance.registrationUri)
// Prints "こんいちは"
var注册uri:String{
得到{
返回字符串(cString:reg_uri)
}
设置{
如果(reg_uri!=nil){
reg_uri.deallocate()
}
newValue.withCString{cString in
//无需添加1,newValue.utf8CString已具有正确的缓冲区容量。
让容量=newValue.utf8CString.count
let buffer:unsafemeutablepointer=.allocate(容量:容量)
buffer.assign(from:cString,count:capacity)
reg_uri=未安全指针(缓冲区)
}
}
}
// ...
myInstance.registrationUri=”こんいちは"
打印(myInstance.registrationUri)
//“印刷品”こんいちは"

谢谢,你在所有方面都是对的。不过我还是不明白这一点:
Swift数组是值类型的实例,谁的生命周期受堆栈的约束
。我的
缓冲区
变量被分配为指针,它是如何绑定到堆栈的?另一个问题:为什么不使用
UnsafeMutableBufferPointer
而不是
不可配置指针
@Alvae@T.Meyer缓冲区是一个Swift数组。Swift数组是值类型('它们被视为类似于结构或枚举')由堆存储支持。值类型在堆栈上分配内存,但如果由堆存储支持,则在堆上分配一部分内存,我觉得当setter退出时,该内存会被释放。我的假设可能再次出错。我在这里也感到困惑。这完全正确@RohanBhale。至于@T.Meyer的第二个问题,
UnsafeMutableBufferPointer
将指针包装为一个存储其容量的int,在我的示例中我不需要它。我个人认为在处理C时,使用
不安全[可变]指针
API更容易。