如何获取 UnsafeMutableRawPointer 的值?

2024-04-04

我试图获取 UnsafeMutableRawPointer 指向的地址,但我无法这样做。我也是 Swift 新手,所以我可能会遗漏一些东西或者做得完全错误。我最好将原始值转换为 CChar。


路人注意:我的大部分回答没有意义,因为它没有回答上面的最初问题,而是回答了中出现的问题chat https://chat.stackoverflow.com/rooms/127974/discussion-between-alexander-momchliov-and-jack-sexton与OP。

我花了几个小时,但现在我已经学会了一些汇编,我可以回答一些问题。

  1. CChar is a C Char... 字面上地。它代表的是char类型C。它是typealias to Int8。它是一个字节。您不能像指针类型一样使用它,因为它们是 8 个字节(在 64 位机器上)。

  2. 你不需要这一切UnsafeMutableRawPointer样板,和你当然不需要访问其原始值。您可以在需要指针的地方直接传递数组。

    当函数被声明为采用 UnsafePointer 参数时,它可以接受以下任何一个:...

    • 一个 [Type] 值,作为指向数组开头的指针传递。

    from 与 C API 交互 - 指针 https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithCAPIs.html#//apple_ref/doc/uid/TP40014216-CH8-ID23.

  3. 您遇到的问题是您的突变0x8(%rdi)似乎并没有体现在Swift方面。这里的问题是你正在以 8 个字节的偏移量写入,但随后print(a.load(as: void_star.self))正在读取第一个字节。您正在读取一个从未修改过的字节。

我做了一些进一步的探索。这是我冒险的战利品:

示例Swift.swift:

@_silgen_name("incrementByValue")
    func incrementByValue(_: Int64)

@_silgen_name("incrementByReference")
    func incrementByReference(_: inout Int64)

@_silgen_name("return1234")
    func return1234() -> Int64

@_silgen_name("incrementElements")
    func incrementElements(of _: UnsafeRawPointer, count _: Int)

var a: Int64 = 100
print("\"a\" before \"incrementByValue(a)\": \(a)")
incrementByValue(a)
print("\"a\" after \"incrementByValue(a)\": \(a)\n")

var b: Int64 = 200
print("\"b\" before \"incrementByValue(b)\": \(b)")
incrementByReference(&b)
print("\"b\" after \"incrementByValue(b)\": \(b)\n")

print("return1234() returned: \(return1234())\n")

var array: [Int64] = Array(0...5)

print("\"array\" before incrementElements(of: array, count: array.count): \n\t\(array)")
incrementElements(of: array, count: array.count)
print("\"array\" after incrementElements(of: array, count: array.count): \n\t\(array)\n")

示例ASM.s:

.text

.globl _incrementByValue
.globl _incrementByReference
.globl _return1234
.globl _incrementElements

// A test routine that demonstrates operating on a value
_incrementByValue:
    // %rdi contains a copy of the argument passed in.
    // Changes here won't be reflected back in Swift
    incq %rdi
    ret

// A test routine that demonstrates operating on a reference
_incrementByReference:
    // %rdi contains a reference tp the argument passed in.
    // Changes to the reference itself won't be reflected back in Swift,
    // but changes to the referenced memory will.
    incq (%rdi)
    ret

// A test routine that demonstrates the use of %rax for returning a value
_return1234:
    movq $1234, %rax    // return value is in rax
    ret

//A test routine that demonstrates operating on an array
_incrementElements:
    // %rdi: Pointer to first of n Int64 elements
    // %rsi: the array count, n

    movq    %rsi, %rcx  // Set loop counter (%rcx) to n
    aLoop:
        incq    (%rdi)      // increment value pointer to by %rdi
        add     $8, %rdi    // advance pointer by 8 bytes
        loop    aLoop       // loop back to aLoop if rcx > 0

    ret

编译、链接并运行:

llvm-g++ -c exampleASM.s &&
swiftc -c exampleSwift.swift &&
ld exampleASM.o exampleSwift.o -o exampleBinary -force_load /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_macosx.a -framework CoreFoundation -macosx_version_min 10.12.0 -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -lobjc -lSystem -arch x86_64 -L /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx -rpath /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/macosx -no_objc_category_merging &&
./exampleBinary

Output:

"a" before "incrementByValue(a)": 100
"a" after "incrementByValue(a)": 100

"b" before "incrementByValue(b)": 200
"b" after "incrementByValue(b)": 201

return1234() returned: 1234

"array" before incrementElements(of: array, count: array.count): 
    [0, 1, 2, 3, 4, 5]
"array" after incrementElements(of: array, count: array.count): 
    [1, 2, 3, 4, 5, 6]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何获取 UnsafeMutableRawPointer 的值? 的相关文章

随机推荐

  • 单次迭代 => 从 Java 到 Scala 的多个输出集合

    我目前正在尝试将一些 Java 代码转换为 Scala 代码 挑战在于确保转换后的 Scala 代码与原始 Java 代码相比不会执行效率非常低的事情 例如当尝试转换以下代码时 class Person String name Intege
  • 关闭 viewController 后重新加载 tableView

    我有一个 ViewController VCA 里面有一个 TableView 从这个 ViewController 可以调用另一个 ViewController VCB 在第二个 VC 中 可以向 plist 添加一个项目 用于填充 VC
  • Twitter消费者密钥和秘密密钥有什么区别?

    我是 Twitter 开发新手 现在 我已经获得了消费者密钥和秘密密钥 但我不知道在哪里使用哪一个 用于登录的简单 JavaScript 代码不起作用 我其实想在推特上发布比赛的比分 任何人请指导我 谢谢 Twitter 有一个很棒的入门指
  • 为什么 readline() 将 stdin 回显到 stdout?

    我写了一个小的 C 程序 使用readline 从 stdin 读取输入 我没有从终端与其进行交互 而是编写了一个测试工具来执行 C 程序并为其提供输入 test harness stdout gt stdin gt C program s
  • 与 .Net 邮件附件一起使用时处置 MemoryStream

    我正在使用 MemoryStream 从存储在数据库中的二进制文件添加附件 我的问题是我想正确处置 MemoryStream 使用 using 语句可以轻松完成此操作 但是当我有多个附件时 我不知道如何正确处理多个 MemoryStream
  • Three.js - 在自定义几何体上平滑兰伯特材质着色的问题

    我在 Three js 中创建了一个自定义几何体 现在 我想创建一个使用平滑阴影兰伯特材质的网格 使用循环 我创建了顶点数组 然后创建了面 然后我调用了 geometry computeCentroids geometry computeF
  • Java BigInteger [重复]

    这个问题在这里已经有答案了 可能的重复 BigInteger 的困难 https stackoverflow com questions 10780209 diffucilty with biginteger import java mat
  • 为什么在内部类中使用公共方法?

    我们的一个项目中有很多代码如下所示 internal static class Extensions public static string AddFoo this string s if s null return Foo return
  • 如何将 Lua 嵌入到 Python 3.x 中?

    是否可以将 Lua 嵌入到 Python 3 x 中 如果是这样 我如何在我的 Python 程序中运行和执行 Lua 脚本 语言之间的交互有多好 例如 Lua 是否可以访问 Python 的所有变量和类以及 Python 是否可以访问 L
  • Angular 2/4 中的嵌套路由

    我正在开发一个应用程序 我打算具有以下结构 MAIN main container main routes NCF lazy loaded routes for it s subapps ACNP lazy loaded Component
  • 需要defaultReadObject()和defaultWriteObject()

    为什么需要写defaultReadObject and defaultWriteObject 作为第一个声明readObject ObjectInputStream o and writeObject ObjectOutputStream
  • 如何根据场景启用/禁用 html 按钮?

    我的网页上有一个带有以下代码的按钮 HTML
  • 使用 data.table 重新编码变量

    我正在尝试使用 data table 重新编码变量 我用谷歌搜索了近2个小时但找不到答案 假设我有一个 data table 如下 DT lt data table V1 c 0L 1L 2L V2 LETTERS 1 3 V4 1 12
  • 何时创建新的 NSURLSession?

    重用的最佳实践是什么NSURLSessions 据我所知 似乎只要配置 超时 缓存策略等 不需要更改 就不需要创建新的配置 因为您可以从中生成新任务 单个也可以NSURLSession可以被整个应用程序重用吗 每个域 端点 按要求 查看文档
  • google buildpack psycopg2-binary 错误:未找到 pg_config 可执行文件

    这是我的requirements txt中的 psycopg2 binary 2 8 3 通过 r requests base in 我正在 docker 镜像中构建 我的印象是 如果我安装psycopg2 binary vs psycop
  • 从 C# 项目内的自定义文件夹获取文件

    第一次海报 也是新手 我创建了一个 C winform 应用程序 我添加了一个 文档 文件夹 其中添加了 5 个 PDF 文件 在我的 Form1 中 我添加了一个按钮 在按钮单击事件中 我尝试从 文档 文件夹中获取文件 我用谷歌搜索了一下
  • File.listFiles() 使用 JDK 6 处理 unicode 名称(Unicode 规范化问题)

    在 OS X 和 Linux 上列出 Java 6 中的目录内容时 我遇到了一个奇怪的文件名编码问题 File listFiles 和相关方法似乎以与系统其他部分不同的编码返回文件名 请注意 给我带来问题的不仅仅是这些文件名的显示 我主要对
  • Laravel 和惯性.js 文件下载

    I uploaded a file to the database and created Storage link using php artisan storage link and everything work perfectly
  • MySQL 中多个表的 COUNT(*)

    如何从 MySQL 的多个表中选择 COUNT Such as SELECT COUNT AS table1Count FROM table1 WHERE someCondition JOIN SELECT COUNT AS table2C
  • 如何获取 UnsafeMutableRawPointer 的值?

    我试图获取 UnsafeMutableRawPointer 指向的地址 但我无法这样做 我也是 Swift 新手 所以我可能会遗漏一些东西或者做得完全错误 我最好将原始值转换为 CChar 路人注意 我的大部分回答没有意义 因为它没有回答上