【问题标题】:Assigning UnsafeMutablePointer value to UnsafePointer without unsafeBitCast在没有 unsafeBitCast 的情况下将 UnsafeMutablePointer 值分配给 UnsafePointer
【发布时间】:2017-06-21 12:49:30
【问题描述】:

我正在使用一个 C API,该 API 使用 const char* 定义一个结构和一个返回 char* 的函数,并试图找到执行分配的最佳方法。

有没有办法在不使用 unsafeBitCast 的情况下做到这一点?如果我不放置演员表,那么我会收到此错误:

Cannot assign value of type 'UnsafeMutablePointer<pchar>' 
(aka 'UnsafeMutablePointer<UInt8>') 
to type 'UnsafePointer<pchar>!' 
(aka 'ImplicitlyUnwrappedOptional<UnsafePointer<UInt8>>')

此外,下面使用 pair() 对 pairPtr 的初始化是否会在堆栈上分配一个 pair 结构来初始化堆上分配的对,因为这对于结构必须被清零的情况来说似乎效率低下。

这里是示例代码:

C 库头文件(最小化以演示问题):

#ifndef __PAIR_INCLUDE__
#define __PAIR_INCLUDE__

typedef unsigned char pchar;

pchar*
pstrdup(const pchar* str);

typedef struct _pair {
    const pchar* left;
    const pchar* right;
} pair;

#endif // __PAIR_INCLUDE__

我的 Swift 代码:

import pair

let leftVal = pstrdup("left")
let rightVal = pstrdup("right")

let pairPtr = UnsafeMutablePointer<pair>.allocate(capacity: 1)
pairPtr.initialize(to: pair())

// Seems like there should be a better way to handle this:
pairPtr.pointee.left = unsafeBitCast(leftVal, to: UnsafePointer<pchar>.self)
pairPtr.pointee.right = unsafeBitCast(rightVal, to: UnsafePointer<pchar>.self)

C 代码:

#include "pair.h"
#include <string.h>

pchar*
pstrdup(const pchar* str) {
    return strdup(str);
}

模块定义:

module pair [extern_c] {
    header "pair.h"
    export *
}

【问题讨论】:

  • 为什么不简单地let p = pair(left: leftVal, right: rightVal) 呢?我不明白为什么需要 unsafeBitCast,也许我忽略了什么?
  • 这可行,但对于真正的结构,有 20 个属性,我只将值分配给大约 5 个。有没有一种简单的方法可以直接分配而无需强制转换?
  • 如果唯一的问题是可变性不同,那么p.left = UnsafePointer(leftVal) 应该可以工作。
  • 是的,您是对的,您能否将其发布为答案,我会接受。我以为我已经尝试过了。顺便说一句,您对这个问题的回答对我也有帮助:stackoverflow.com/questions/33294620/…

标签: swift pointers swift3 casting unsafe-pointers


【解决方案1】:

您可以从UnsafeMutablePtr&lt;T&gt; 创建一个UnsafePointer&lt;T&gt; 简单地用

let ptr = UnsafePointer(mptr)

使用

/// Creates an immutable typed pointer referencing the same memory as the
/// given mutable pointer.
///
/// - Parameter other: The pointer to convert.
public init(_ other: UnsafeMutablePointer<Pointee>)

UnsafePointer 的初始化器。在您的情况下,例如

p.left = UnsafePointer(leftVal)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-01
    • 2010-10-07
    • 2019-11-02
    • 1970-01-01
    • 2012-11-28
    • 1970-01-01
    • 2010-09-07
    相关资源
    最近更新 更多